1 /* 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 $Id: exceptions.c 1935 2005-02-10 11:01:26Z twisti $
40 #include "mm/memory.h"
41 #include "native/native.h"
42 #include "native/include/java_lang_String.h"
43 #include "native/include/java_lang_Throwable.h"
44 #include "toolbox/logging.h"
46 #include "vm/exceptions.h"
47 #include "vm/global.h"
48 #include "vm/loader.h"
49 #include "vm/options.h"
50 #include "vm/stringlocal.h"
51 #include "vm/tables.h"
52 #include "vm/jit/asmpart.h"
53 #include "vm/jit/jit.h"
56 /* for raising exceptions from native methods */
58 #if !defined(USE_THREADS) || !defined(NATIVE_THREADS)
59 java_objectheader* _exceptionptr = NULL;
63 /* exception/error super class */
65 const char *string_java_lang_Throwable =
66 "java/lang/Throwable";
68 const char *string_java_lang_VMThrowable =
69 "java/lang/VMThrowable";
72 /* specify some exception strings for code generation */
74 const char *string_java_lang_ArithmeticException =
75 "java/lang/ArithmeticException";
77 const char *string_java_lang_ArithmeticException_message =
80 const char *string_java_lang_ArrayIndexOutOfBoundsException =
81 "java/lang/ArrayIndexOutOfBoundsException";
83 const char *string_java_lang_ArrayStoreException =
84 "java/lang/ArrayStoreException";
86 const char *string_java_lang_ClassCastException =
87 "java/lang/ClassCastException";
89 const char *string_java_lang_ClassNotFoundException =
90 "java/lang/ClassNotFoundException";
92 const char *string_java_lang_CloneNotSupportedException =
93 "java/lang/CloneNotSupportedException";
95 const char *string_java_lang_Exception =
96 "java/lang/Exception";
98 const char *string_java_lang_IllegalAccessException =
99 "java/lang/IllegalAccessException";
101 const char *string_java_lang_IllegalArgumentException =
102 "java/lang/IllegalArgumentException";
104 const char *string_java_lang_IllegalMonitorStateException =
105 "java/lang/IllegalMonitorStateException";
107 const char *string_java_lang_IndexOutOfBoundsException =
108 "java/lang/IndexOutOfBoundsException";
110 const char *string_java_lang_InstantiationException =
111 "java/lang/InstantiationException";
113 const char *string_java_lang_InterruptedException =
114 "java/lang/InterruptedException";
116 const char *string_java_lang_NegativeArraySizeException =
117 "java/lang/NegativeArraySizeException";
119 const char *string_java_lang_NoSuchFieldException =
120 "java/lang/NoSuchFieldException";
122 const char *string_java_lang_NoSuchMethodException =
123 "java/lang/NoSuchMethodException";
125 const char *string_java_lang_NullPointerException =
126 "java/lang/NullPointerException";
129 /* specify some error strings for code generation */
131 const char *string_java_lang_AbstractMethodError =
132 "java/lang/AbstractMethodError";
134 const char *string_java_lang_ClassCircularityError =
135 "java/lang/ClassCircularityError";
137 const char *string_java_lang_ClassFormatError =
138 "java/lang/ClassFormatError";
140 const char *string_java_lang_Error =
143 const char *string_java_lang_ExceptionInInitializerError =
144 "java/lang/ExceptionInInitializerError";
146 const char *string_java_lang_IncompatibleClassChangeError =
147 "java/lang/IncompatibleClassChangeError";
149 const char *string_java_lang_InternalError =
150 "java/lang/InternalError";
152 const char *string_java_lang_LinkageError =
153 "java/lang/LinkageError";
155 const char *string_java_lang_NoClassDefFoundError =
156 "java/lang/NoClassDefFoundError";
158 const char *string_java_lang_NoSuchFieldError =
159 "java/lang/NoSuchFieldError";
161 const char *string_java_lang_NoSuchMethodError =
162 "java/lang/NoSuchMethodError";
164 const char *string_java_lang_OutOfMemoryError =
165 "java/lang/OutOfMemoryError";
167 const char *string_java_lang_UnsupportedClassVersionError =
168 "java/lang/UnsupportedClassVersionError";
170 const char *string_java_lang_VerifyError =
171 "java/lang/VerifyError";
173 const char *string_java_lang_VirtualMachineError =
174 "java/lang/VirtualMachineError";
177 /* init_system_exceptions ******************************************************
179 Load and link exceptions used in the system.
181 *******************************************************************************/
183 bool exceptions_init(void)
185 /* java/lang/Throwable */
187 if (!class_load(class_java_lang_Throwable) ||
188 !class_link(class_java_lang_Throwable))
192 /* java/lang/Exception */
194 if (!class_load(class_java_lang_Exception) ||
195 !class_link(class_java_lang_Exception))
199 /* java/lang/Error */
201 if (!class_load(class_java_lang_Error) ||
202 !class_link(class_java_lang_Error))
206 /* java/lang/OutOfMemoryError */
208 if (!class_load(class_java_lang_OutOfMemoryError) ||
209 !class_link(class_java_lang_OutOfMemoryError))
216 static void throw_exception_exit_intern(bool doexit)
218 java_objectheader *xptr;
222 xptr = *exceptionptr;
225 /* clear exception, because we are calling jit code again */
226 *exceptionptr = NULL;
228 c = xptr->vftbl->class;
230 pss = class_resolveclassmethod(c,
233 class_java_lang_Object,
236 /* print the stacktrace */
238 asm_calljavafunction(pss, xptr, NULL, NULL, NULL);
240 /* this normally means, we are EXTREMLY out of memory, but may be
241 any other exception */
243 utf_fprint_classname(stderr, c->name);
244 fprintf(stderr, "\n");
248 utf_fprint_classname(stderr, c->name);
249 fprintf(stderr, ": printStackTrace()V not found!\n");
262 void throw_exception()
264 throw_exception_exit_intern(false);
268 void throw_exception_exit()
270 throw_exception_exit_intern(true);
274 void throw_main_exception()
276 fprintf(stderr, "Exception in thread \"main\" ");
279 throw_exception_exit_intern(false);
283 void throw_main_exception_exit()
285 fprintf(stderr, "Exception in thread \"main\" ");
288 throw_exception_exit_intern(true);
292 void throw_cacao_exception_exit(const char *exception, const char *message, ...)
299 len = strlen(exception);
300 tmp = MNEW(char, len + 1);
301 strncpy(tmp, exception, len);
304 /* convert to classname */
306 for (i = len - 1; i >= 0; i--)
307 if (tmp[i] == '/') tmp[i] = '.';
309 fprintf(stderr, "Exception in thread \"main\" %s", tmp);
311 MFREE(tmp, char, len);
313 if (strlen(message) > 0) {
314 fprintf(stderr, ": ");
316 va_start(ap, message);
317 vfprintf(stderr, message, ap);
321 fprintf(stderr, "\n");
330 java_objectheader *new_exception(const char *classname)
332 classinfo *c = class_new(utf_new_char(classname));
334 return native_new_and_init(c);
337 java_objectheader *new_exception_message(const char *classname, const char *message)
339 classinfo *c = class_new(utf_new_char(classname));
341 return native_new_and_init_string(c, javastring_new_char(message));
345 java_objectheader *new_exception_throwable(const char *classname, java_lang_Throwable *throwable)
347 classinfo *c = class_new(utf_new_char(classname));
349 return native_new_and_init_throwable(c, throwable);
353 java_objectheader *new_exception_utfmessage(const char *classname, utf *message)
355 classinfo *c = class_new(utf_new_char(classname));
357 return native_new_and_init_string(c, javastring_new(message));
361 java_objectheader *new_exception_javastring(const char *classname, java_lang_String *message)
363 classinfo *c = class_new(utf_new_char(classname));
365 return native_new_and_init_string(c, message);
369 java_objectheader *new_exception_int(const char *classname, s4 i)
373 c = class_new(utf_new_char(classname));
375 return native_new_and_init_int(c, i);
379 /* new_classformaterror ********************************************************
381 generates a java.lang.ClassFormatError for the classloader
383 *******************************************************************************/
385 java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
387 char msg[MAXLOGTEXT];
390 utf_sprint_classname(msg, c->name);
391 sprintf(msg + strlen(msg), " (");
393 va_start(ap, message);
394 vsprintf(msg + strlen(msg), message, ap);
397 sprintf(msg + strlen(msg), ")");
399 return new_exception_message(string_java_lang_ClassFormatError, msg);
403 /* new_unsupportedclassversionerror ********************************************
405 generates a java.lang.UnsupportedClassVersionError for the classloader
407 *******************************************************************************/
409 java_objectheader *new_unsupportedclassversionerror(classinfo *c, const char *message, ...)
411 char msg[MAXLOGTEXT];
414 utf_sprint_classname(msg, c->name);
415 sprintf(msg + strlen(msg), " (");
417 va_start(ap, message);
418 vsprintf(msg + strlen(msg), message, ap);
421 sprintf(msg + strlen(msg), ")");
423 return new_exception_message(string_java_lang_UnsupportedClassVersionError,
428 /* new_verifyerror *************************************************************
430 generates a java.lang.VerifyError for the jit compiler
432 *******************************************************************************/
434 java_objectheader *new_verifyerror(methodinfo *m, const char *message)
436 java_objectheader *o;
440 useinlining = false; /* at least until sure inlining works with exceptions*/
441 len = 8 + utf_strlen(m->class->name) +
442 10 + utf_strlen(m->name) +
443 13 + utf_strlen(m->descriptor) +
444 2 + strlen(message) + 1;
446 msg = MNEW(char, len);
448 sprintf(msg, "(class: ");
449 utf_sprint(msg + strlen(msg), m->class->name);
450 sprintf(msg + strlen(msg), ", method: ");
451 utf_sprint(msg + strlen(msg), m->name);
452 sprintf(msg + strlen(msg), ", signature: ");
453 utf_sprint(msg + strlen(msg), m->descriptor);
454 sprintf(msg + strlen(msg), ") %s", message);
456 o = new_exception_message(string_java_lang_VerifyError, msg);
464 /* new_arithmeticexception *****************************************************
466 generates a java.lang.ArithmeticException for the jit compiler
468 *******************************************************************************/
470 java_objectheader *new_arithmeticexception()
472 java_objectheader *e;
474 e = new_exception_message(string_java_lang_ArithmeticException,
475 string_java_lang_ArithmeticException_message);
478 return *exceptionptr;
484 /* new_arrayindexoutofboundsexception ******************************************
486 generates a java.lang.ArrayIndexOutOfBoundsException for the jit compiler
488 *******************************************************************************/
490 java_objectheader *new_arrayindexoutofboundsexception(s4 index)
492 java_objectheader *e;
496 /* convert the index into a String, like Sun does */
498 m = class_resolveclassmethod(class_java_lang_String,
499 utf_new_char("valueOf"),
500 utf_new_char("(I)Ljava/lang/String;"),
501 class_java_lang_Object,
505 return *exceptionptr;
507 s = (java_lang_String *) asm_calljavafunction(m,
518 return *exceptionptr;
520 e = new_exception_javastring(string_java_lang_ArrayIndexOutOfBoundsException,
524 return *exceptionptr;
530 /* new_arraystoreexception *****************************************************
532 generates a java.lang.ArrayStoreException for the jit compiler
534 *******************************************************************************/
536 java_objectheader *new_arraystoreexception()
538 java_objectheader *e;
540 e = new_exception(string_java_lang_ArrayStoreException);
543 return *exceptionptr;
549 /* new_classcastexception ******************************************************
551 generates a java.lang.ClassCastException for the jit compiler
553 *******************************************************************************/
555 java_objectheader *new_classcastexception()
557 java_objectheader *e;
559 e = new_exception(string_java_lang_ClassCastException);
562 return *exceptionptr;
568 /* new_negativearraysizeexception **********************************************
570 generates a java.lang.NegativeArraySizeException for the jit compiler
572 *******************************************************************************/
574 java_objectheader *new_negativearraysizeexception()
576 java_objectheader *e;
578 e = new_exception(string_java_lang_NegativeArraySizeException);
581 return *exceptionptr;
587 /* new_nullpointerexception ****************************************************
589 generates a java.lang.NullPointerException for the jit compiler
591 *******************************************************************************/
593 java_objectheader *new_nullpointerexception()
595 java_objectheader *e;
597 e = new_exception(string_java_lang_NullPointerException);
600 return *exceptionptr;
607 * These are local overrides for various environment variables in Emacs.
608 * Please do not remove this and leave it at the end of the file, where
609 * Emacs will automagically detect them.
610 * ---------------------------------------------------------------------
613 * indent-tabs-mode: t