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 2193 2005-04-02 19:33:43Z 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"
48 #include "vm/exceptions.h"
49 #include "vm/global.h"
50 #include "vm/loader.h"
51 #include "vm/options.h"
52 #include "vm/stringlocal.h"
53 #include "vm/tables.h"
54 #include "vm/jit/asmpart.h"
55 #include "vm/jit/jit.h"
58 /* for raising exceptions from native methods */
60 #if !defined(USE_THREADS) || !defined(NATIVE_THREADS)
61 java_objectheader* _exceptionptr = NULL;
65 /* exception/error super class */
67 const char *string_java_lang_Throwable =
68 "java/lang/Throwable";
70 const char *string_java_lang_VMThrowable =
71 "java/lang/VMThrowable";
74 /* specify some exception strings for code generation */
76 const char *string_java_lang_ArithmeticException =
77 "java/lang/ArithmeticException";
79 const char *string_java_lang_ArithmeticException_message =
82 const char *string_java_lang_ArrayIndexOutOfBoundsException =
83 "java/lang/ArrayIndexOutOfBoundsException";
85 const char *string_java_lang_ArrayStoreException =
86 "java/lang/ArrayStoreException";
88 const char *string_java_lang_ClassCastException =
89 "java/lang/ClassCastException";
91 const char *string_java_lang_ClassNotFoundException =
92 "java/lang/ClassNotFoundException";
94 const char *string_java_lang_CloneNotSupportedException =
95 "java/lang/CloneNotSupportedException";
97 const char *string_java_lang_Exception =
98 "java/lang/Exception";
100 const char *string_java_lang_IllegalAccessException =
101 "java/lang/IllegalAccessException";
103 const char *string_java_lang_IllegalArgumentException =
104 "java/lang/IllegalArgumentException";
106 const char *string_java_lang_IllegalMonitorStateException =
107 "java/lang/IllegalMonitorStateException";
109 const char *string_java_lang_IndexOutOfBoundsException =
110 "java/lang/IndexOutOfBoundsException";
112 const char *string_java_lang_InstantiationException =
113 "java/lang/InstantiationException";
115 const char *string_java_lang_InterruptedException =
116 "java/lang/InterruptedException";
118 const char *string_java_lang_NegativeArraySizeException =
119 "java/lang/NegativeArraySizeException";
121 const char *string_java_lang_NoSuchFieldException =
122 "java/lang/NoSuchFieldException";
124 const char *string_java_lang_NoSuchMethodException =
125 "java/lang/NoSuchMethodException";
127 const char *string_java_lang_NullPointerException =
128 "java/lang/NullPointerException";
131 /* specify some error strings for code generation */
133 const char *string_java_lang_AbstractMethodError =
134 "java/lang/AbstractMethodError";
136 const char *string_java_lang_ClassCircularityError =
137 "java/lang/ClassCircularityError";
139 const char *string_java_lang_ClassFormatError =
140 "java/lang/ClassFormatError";
142 const char *string_java_lang_Error =
145 const char *string_java_lang_ExceptionInInitializerError =
146 "java/lang/ExceptionInInitializerError";
148 const char *string_java_lang_IncompatibleClassChangeError =
149 "java/lang/IncompatibleClassChangeError";
151 const char *string_java_lang_InternalError =
152 "java/lang/InternalError";
154 const char *string_java_lang_LinkageError =
155 "java/lang/LinkageError";
157 const char *string_java_lang_NoClassDefFoundError =
158 "java/lang/NoClassDefFoundError";
160 const char *string_java_lang_NoSuchFieldError =
161 "java/lang/NoSuchFieldError";
163 const char *string_java_lang_NoSuchMethodError =
164 "java/lang/NoSuchMethodError";
166 const char *string_java_lang_OutOfMemoryError =
167 "java/lang/OutOfMemoryError";
169 const char *string_java_lang_UnsupportedClassVersionError =
170 "java/lang/UnsupportedClassVersionError";
172 const char *string_java_lang_VerifyError =
173 "java/lang/VerifyError";
175 const char *string_java_lang_VirtualMachineError =
176 "java/lang/VirtualMachineError";
179 /* init_system_exceptions ******************************************************
181 Load and link exceptions used in the system.
183 *******************************************************************************/
185 bool exceptions_init(void)
187 /* java/lang/Throwable */
189 if (!load_class_bootstrap(utf_java_lang_Throwable,&class_java_lang_Throwable) ||
190 !link_class(class_java_lang_Throwable))
194 /* java/lang/Exception */
196 if (!load_class_bootstrap(utf_java_lang_Exception,&class_java_lang_Exception) ||
197 !link_class(class_java_lang_Exception))
201 /* java/lang/Error */
203 if (!load_class_bootstrap(utf_java_lang_Error,&class_java_lang_Error) ||
204 !link_class(class_java_lang_Error))
208 /* java/lang/OutOfMemoryError */
210 if (!load_class_bootstrap(utf_java_lang_OutOfMemoryError,&class_java_lang_OutOfMemoryError) ||
211 !link_class(class_java_lang_OutOfMemoryError))
218 static void throw_exception_exit_intern(bool doexit)
220 java_objectheader *xptr;
224 xptr = *exceptionptr;
227 /* clear exception, because we are calling jit code again */
228 *exceptionptr = NULL;
230 c = xptr->vftbl->class;
232 pss = class_resolveclassmethod(c,
235 class_java_lang_Object,
238 /* print the stacktrace */
240 asm_calljavafunction(pss, xptr, NULL, NULL, NULL);
242 /* this normally means, we are EXTREMLY out of memory, but may be
243 any other exception */
245 utf_fprint_classname(stderr, c->name);
246 fprintf(stderr, "\n");
250 utf_fprint_classname(stderr, c->name);
251 fprintf(stderr, ": printStackTrace()V not found!\n");
264 void throw_exception()
266 throw_exception_exit_intern(false);
270 void throw_exception_exit()
272 throw_exception_exit_intern(true);
276 void throw_main_exception()
278 fprintf(stderr, "Exception in thread \"main\" ");
281 throw_exception_exit_intern(false);
285 void throw_main_exception_exit()
287 fprintf(stderr, "Exception in thread \"main\" ");
290 throw_exception_exit_intern(true);
294 void throw_cacao_exception_exit(const char *exception, const char *message, ...)
301 len = strlen(exception);
302 tmp = MNEW(char, len + 1);
303 strncpy(tmp, exception, len);
306 /* convert to classname */
308 for (i = len - 1; i >= 0; i--)
309 if (tmp[i] == '/') tmp[i] = '.';
311 fprintf(stderr, "Exception in thread \"main\" %s", tmp);
313 MFREE(tmp, char, len);
315 if (strlen(message) > 0) {
316 fprintf(stderr, ": ");
318 va_start(ap, message);
319 vfprintf(stderr, message, ap);
323 fprintf(stderr, "\n");
332 java_objectheader *new_exception(const char *classname)
336 if (!load_class_bootstrap(utf_new_char(classname),&c))
337 return *exceptionptr;
339 return native_new_and_init(c);
342 java_objectheader *new_exception_message(const char *classname, const char *message)
346 if (!load_class_bootstrap(utf_new_char(classname),&c))
347 return *exceptionptr;
350 return native_new_and_init_string(c, javastring_new_char(message));
354 java_objectheader *new_exception_throwable(const char *classname, java_lang_Throwable *throwable)
358 if (!load_class_bootstrap(utf_new_char(classname),&c))
359 return *exceptionptr;
362 return native_new_and_init_throwable(c, throwable);
366 java_objectheader *new_exception_utfmessage(const char *classname, utf *message)
370 if (!load_class_bootstrap(utf_new_char(classname),&c))
371 return *exceptionptr;
374 return native_new_and_init_string(c, javastring_new(message));
378 java_objectheader *new_exception_javastring(const char *classname, java_lang_String *message)
382 if (!load_class_bootstrap(utf_new_char(classname),&c))
383 return *exceptionptr;
386 return native_new_and_init_string(c, message);
390 java_objectheader *new_exception_int(const char *classname, s4 i)
394 if (!load_class_bootstrap(utf_new_char(classname),&c))
395 return *exceptionptr;
397 return native_new_and_init_int(c, i);
401 /* new_classformaterror ********************************************************
403 generates a java.lang.ClassFormatError for the classloader
405 *******************************************************************************/
407 java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
409 char msg[MAXLOGTEXT];
412 utf_sprint_classname(msg, c->name);
413 sprintf(msg + strlen(msg), " (");
415 va_start(ap, message);
416 vsprintf(msg + strlen(msg), message, ap);
419 sprintf(msg + strlen(msg), ")");
421 return new_exception_message(string_java_lang_ClassFormatError, msg);
425 /* new_internalerror ***********************************************************
427 Generates a java.lang.InternalError for the VM.
429 *******************************************************************************/
431 java_objectheader *new_internalerror(const char *message, ...)
433 char msg[MAXLOGTEXT];
436 va_start(ap, message);
437 vsprintf(msg, message, ap);
440 return new_exception_message(string_java_lang_InternalError, msg);
444 /* new_unsupportedclassversionerror ********************************************
446 generates a java.lang.UnsupportedClassVersionError for the classloader
448 *******************************************************************************/
450 java_objectheader *new_unsupportedclassversionerror(classinfo *c, const char *message, ...)
452 char msg[MAXLOGTEXT];
455 utf_sprint_classname(msg, c->name);
456 sprintf(msg + strlen(msg), " (");
458 va_start(ap, message);
459 vsprintf(msg + strlen(msg), message, ap);
462 sprintf(msg + strlen(msg), ")");
464 return new_exception_message(string_java_lang_UnsupportedClassVersionError,
469 /* new_verifyerror *************************************************************
471 generates a java.lang.VerifyError for the jit compiler
473 *******************************************************************************/
475 java_objectheader *new_verifyerror(methodinfo *m, const char *message)
477 java_objectheader *o;
481 useinlining = false; /* at least until sure inlining works with exceptions*/
482 len = 8 + utf_strlen(m->class->name) +
483 10 + utf_strlen(m->name) +
484 13 + utf_strlen(m->descriptor) +
485 2 + strlen(message) + 1;
487 msg = MNEW(char, len);
489 sprintf(msg, "(class: ");
490 utf_sprint(msg + strlen(msg), m->class->name);
491 sprintf(msg + strlen(msg), ", method: ");
492 utf_sprint(msg + strlen(msg), m->name);
493 sprintf(msg + strlen(msg), ", signature: ");
494 utf_sprint(msg + strlen(msg), m->descriptor);
495 sprintf(msg + strlen(msg), ") %s", message);
497 o = new_exception_message(string_java_lang_VerifyError, msg);
505 /* new_arithmeticexception *****************************************************
507 generates a java.lang.ArithmeticException for the jit compiler
509 *******************************************************************************/
511 java_objectheader *new_arithmeticexception()
513 java_objectheader *e;
515 e = new_exception_message(string_java_lang_ArithmeticException,
516 string_java_lang_ArithmeticException_message);
519 return *exceptionptr;
525 /* new_arrayindexoutofboundsexception ******************************************
527 generates a java.lang.ArrayIndexOutOfBoundsException for the jit compiler
529 *******************************************************************************/
531 java_objectheader *new_arrayindexoutofboundsexception(s4 index)
533 java_objectheader *e;
537 /* convert the index into a String, like Sun does */
539 m = class_resolveclassmethod(class_java_lang_String,
540 utf_new_char("valueOf"),
541 utf_new_char("(I)Ljava/lang/String;"),
542 class_java_lang_Object,
546 return *exceptionptr;
548 s = (java_lang_String *) asm_calljavafunction(m,
559 return *exceptionptr;
561 e = new_exception_javastring(string_java_lang_ArrayIndexOutOfBoundsException,
565 return *exceptionptr;
571 /* new_arraystoreexception *****************************************************
573 generates a java.lang.ArrayStoreException for the jit compiler
575 *******************************************************************************/
577 java_objectheader *new_arraystoreexception()
579 java_objectheader *e;
581 e = new_exception(string_java_lang_ArrayStoreException);
584 return *exceptionptr;
590 /* new_classcastexception ******************************************************
592 generates a java.lang.ClassCastException for the jit compiler
594 *******************************************************************************/
596 java_objectheader *new_classcastexception()
598 java_objectheader *e;
600 e = new_exception(string_java_lang_ClassCastException);
603 return *exceptionptr;
609 /* new_negativearraysizeexception **********************************************
611 generates a java.lang.NegativeArraySizeException for the jit compiler
613 *******************************************************************************/
615 java_objectheader *new_negativearraysizeexception()
617 java_objectheader *e;
619 e = new_exception(string_java_lang_NegativeArraySizeException);
622 return *exceptionptr;
628 /* new_nullpointerexception ****************************************************
630 generates a java.lang.NullPointerException for the jit compiler
632 *******************************************************************************/
634 java_objectheader *new_nullpointerexception()
636 java_objectheader *e;
638 e = new_exception(string_java_lang_NullPointerException);
641 return *exceptionptr;
648 * These are local overrides for various environment variables in Emacs.
649 * Please do not remove this and leave it at the end of the file, where
650 * Emacs will automagically detect them.
651 * ---------------------------------------------------------------------
654 * indent-tabs-mode: t