1 /* src/vm/exceptions.cpp - exception related functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
38 #include "mm/memory.h"
40 #include "native/jni.h"
41 #include "native/llni.h"
42 #include "native/native.h"
44 #include "threads/lock-common.h"
45 #include "threads/thread.hpp"
47 #include "toolbox/util.h"
49 #include "vm/builtin.h"
51 #include "vm/exceptions.hpp"
52 #include "vm/global.h"
53 #include "vm/globals.hpp"
54 #include "vm/javaobjects.hpp"
55 #include "vm/loader.h"
56 #include "vm/method.h"
57 #include "vm/options.h"
59 #include "vm/string.hpp"
62 #include "vm/jit/asmpart.h"
63 #include "vm/jit/jit.h"
64 #include "vm/jit/methodheader.h"
65 #include "vm/jit/patcher-common.h"
66 #include "vm/jit/show.h"
67 #include "vm/jit/stacktrace.hpp"
68 #include "vm/jit/trace.hpp"
70 #if defined(ENABLE_VMLOG)
71 #include <vmlog_cacao.h>
78 /* for raising exceptions from native methods *********************************/
80 #if !defined(ENABLE_THREADS)
81 java_object_t *_no_threads_exceptionptr = NULL;
85 /* exceptions_get_exception ****************************************************
87 Returns the current exception pointer of the current thread.
89 *******************************************************************************/
91 java_handle_t *exceptions_get_exception(void)
95 #if defined(ENABLE_THREADS)
101 /* Get the exception. */
105 #if defined(ENABLE_THREADS)
106 o = t->_exceptionptr;
108 o = _no_threads_exceptionptr;
115 /* Return the exception. */
121 /* exceptions_set_exception ****************************************************
123 Sets the exception pointer of the current thread.
125 *******************************************************************************/
127 void exceptions_set_exception(java_handle_t *e)
132 #if defined(ENABLE_THREADS)
138 /* Set the exception. */
145 if (opt_DebugExceptions) {
146 printf("[exceptions_set_exception : t=%p, o=%p, class=",
147 (void *) t, (void *) o);
148 class_print(o->vftbl->clazz);
153 #if defined(ENABLE_THREADS)
154 t->_exceptionptr = o;
156 _no_threads_exceptionptr = o;
163 /* exceptions_clear_exception **************************************************
165 Clears the current exception pointer of the current thread.
167 *******************************************************************************/
169 void exceptions_clear_exception(void)
173 #if defined(ENABLE_THREADS)
179 /* Set the exception. */
182 if (opt_DebugExceptions) {
183 printf("[exceptions_clear_exception: t=%p]\n", (void *) t);
187 #if defined(ENABLE_THREADS)
188 t->_exceptionptr = NULL;
190 _no_threads_exceptionptr = NULL;
195 /* exceptions_get_and_clear_exception ******************************************
197 Gets the exception pointer of the current thread and clears it.
198 This function may return NULL.
200 *******************************************************************************/
202 java_handle_t *exceptions_get_and_clear_exception(void)
206 /* Get the exception... */
208 o = exceptions_get_exception();
210 /* ...and clear the exception if it is set. */
213 exceptions_clear_exception();
215 /* return the exception */
221 /* exceptions_abort ************************************************************
223 Prints exception to be thrown and aborts.
226 classname....class name
227 message......exception message
229 *******************************************************************************/
231 static void exceptions_abort(utf *classname, utf *message)
233 log_println("exception thrown while VM is initializing: ");
236 utf_display_printable_ascii_classname(classname);
238 if (message != NULL) {
240 utf_display_printable_ascii_classname(message);
245 vm_abort("Aborting...");
249 /* exceptions_new_class_utf ****************************************************
251 Creates an exception object with the given class and initalizes it
252 with the given utf message.
255 c ......... exception class
256 message ... the message as an utf *
259 an exception pointer (in any case -- either it is the newly
260 created exception, or an exception thrown while trying to create
263 *******************************************************************************/
265 static java_handle_t *exceptions_new_class_utf(classinfo *c, utf *message)
270 if (vm->is_initializing()) {
271 /* This can happen when global class variables are used which
272 are not initialized yet. */
275 exceptions_abort(NULL, message);
277 exceptions_abort(c->name, message);
280 s = javastring_new(message);
283 return exceptions_get_exception();
285 o = native_new_and_init_string(c, s);
288 return exceptions_get_exception();
294 /* exceptions_new_utf **********************************************************
296 Creates an exception object with the given name and initalizes it.
299 classname....class name in UTF-8
301 *******************************************************************************/
303 static java_handle_t *exceptions_new_utf(utf *classname)
308 if (vm->is_initializing())
309 exceptions_abort(classname, NULL);
311 c = load_class_bootstrap(classname);
314 return exceptions_get_exception();
316 o = native_new_and_init(c);
319 return exceptions_get_exception();
325 /* exceptions_new_utf_javastring ***********************************************
327 Creates an exception object with the given name and initalizes it
328 with the given java/lang/String message.
331 classname....class name in UTF-8
332 message......the message as a java.lang.String
335 an exception pointer (in any case -- either it is the newly created
336 exception, or an exception thrown while trying to create it).
338 *******************************************************************************/
340 static java_handle_t *exceptions_new_utf_javastring(utf *classname,
341 java_handle_t *message)
346 if (vm->is_initializing())
347 exceptions_abort(classname, NULL);
349 c = load_class_bootstrap(classname);
352 return exceptions_get_exception();
354 o = native_new_and_init_string(c, message);
357 return exceptions_get_exception();
363 /* exceptions_new_utf_utf ******************************************************
365 Creates an exception object with the given name and initalizes it
366 with the given utf message.
369 classname....class name in UTF-8
370 message......the message as an utf *
373 an exception pointer (in any case -- either it is the newly created
374 exception, or an exception thrown while trying to create it).
376 *******************************************************************************/
378 static java_handle_t *exceptions_new_utf_utf(utf *classname, utf *message)
383 if (vm->is_initializing())
384 exceptions_abort(classname, message);
386 c = load_class_bootstrap(classname);
389 return exceptions_get_exception();
391 o = exceptions_new_class_utf(c, message);
397 /* exceptions_throw_class_utf **************************************************
399 Creates an exception object with the given class, initalizes and
400 throws it with the given utf message.
403 c ......... exception class
404 message ... the message as an utf *
406 *******************************************************************************/
408 static void exceptions_throw_class_utf(classinfo *c, utf *message)
412 o = exceptions_new_class_utf(c, message);
414 exceptions_set_exception(o);
418 /* exceptions_throw_utf ********************************************************
420 Creates an exception object with the given name, initalizes and
424 classname....class name in UTF-8
426 *******************************************************************************/
428 static void exceptions_throw_utf(utf *classname)
432 o = exceptions_new_utf(classname);
437 exceptions_set_exception(o);
441 /* exceptions_throw_utf_throwable **********************************************
443 Creates an exception object with the given name and initalizes it
444 with the given java/lang/Throwable exception.
447 classname....class name in UTF-8
448 cause........the given Throwable
450 *******************************************************************************/
452 static void exceptions_throw_utf_throwable(utf *classname,
453 java_handle_t *cause)
458 if (vm->is_initializing())
459 exceptions_abort(classname, NULL);
461 java_lang_Throwable jlt(cause);
463 c = load_class_bootstrap(classname);
470 java_handle_t* h = builtin_new(c);
475 /* call initializer */
477 m = class_resolveclassmethod(c,
479 utf_java_lang_Throwable__void,
486 (void) vm_call_method(m, h, jlt.get_handle());
488 exceptions_set_exception(h);
492 /* exceptions_throw_utf_exception **********************************************
494 Creates an exception object with the given name and initalizes it
495 with the given java/lang/Exception exception.
498 classname....class name in UTF-8
499 exception....the given Exception
501 *******************************************************************************/
503 static void exceptions_throw_utf_exception(utf *classname,
504 java_handle_t *exception)
510 if (vm->is_initializing())
511 exceptions_abort(classname, NULL);
513 c = load_class_bootstrap(classname);
525 /* call initializer */
527 m = class_resolveclassmethod(c,
529 utf_java_lang_Exception__V,
536 (void) vm_call_method(m, o, exception);
538 exceptions_set_exception(o);
542 /* exceptions_throw_utf_cause **************************************************
544 Creates an exception object with the given name and initalizes it
545 with the given java/lang/Throwable exception with initCause.
548 classname....class name in UTF-8
549 cause........the given Throwable
551 *******************************************************************************/
553 static void exceptions_throw_utf_cause(utf *classname, java_handle_t *cause)
555 if (vm->is_initializing())
556 exceptions_abort(classname, NULL);
558 java_lang_Throwable jltcause(cause);
560 classinfo* c = load_class_bootstrap(classname);
567 java_handle_t* h = builtin_new(c);
572 /* call initializer */
574 methodinfo* m = class_resolveclassmethod(c,
576 utf_java_lang_String__void,
583 (void) vm_call_method(m, h, jltcause.get_detailMessage());
587 m = class_resolveclassmethod(c,
589 utf_java_lang_Throwable__java_lang_Throwable,
596 (void) vm_call_method(m, h, jltcause.get_handle());
598 exceptions_set_exception(h);
602 /* exceptions_throw_utf_utf ****************************************************
604 Creates an exception object with the given name, initalizes and
605 throws it with the given utf message.
608 classname....class name in UTF-8
609 message......the message as an utf *
611 *******************************************************************************/
613 static void exceptions_throw_utf_utf(utf *classname, utf *message)
617 o = exceptions_new_utf_utf(classname, message);
619 exceptions_set_exception(o);
623 /* exceptions_new_abstractmethoderror ****************************************
625 Generates a java.lang.AbstractMethodError for the VM.
627 *******************************************************************************/
629 java_handle_t *exceptions_new_abstractmethoderror(void)
633 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
639 /* exceptions_new_error ********************************************************
641 Generates a java.lang.Error for the VM.
643 *******************************************************************************/
645 #if defined(ENABLE_JAVAME_CLDC1_1)
646 static java_handle_t *exceptions_new_error(utf *message)
650 o = exceptions_new_utf_utf(utf_java_lang_Error, message);
657 /* exceptions_asm_new_abstractmethoderror **************************************
659 Generates a java.lang.AbstractMethodError for
660 asm_abstractmethoderror.
662 *******************************************************************************/
664 java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
666 stackframeinfo_t sfi;
670 /* Fill and add a stackframeinfo (XPC is equal to RA). */
672 stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra);
674 /* create the exception */
676 #if defined(ENABLE_JAVASE)
677 e = exceptions_new_abstractmethoderror();
679 e = exceptions_new_error(utf_java_lang_AbstractMethodError);
682 /* Remove the stackframeinfo. */
684 stacktrace_stackframeinfo_remove(&sfi);
686 /* unwrap the exception */
687 /* ATTENTION: do the this _after_ the stackframeinfo was removed */
695 /* exceptions_new_arraystoreexception ******************************************
697 Generates a java.lang.ArrayStoreException for the VM.
699 *******************************************************************************/
701 java_handle_t *exceptions_new_arraystoreexception(void)
705 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
711 /* exceptions_throw_abstractmethoderror ****************************************
713 Generates and throws a java.lang.AbstractMethodError for the VM.
715 *******************************************************************************/
717 void exceptions_throw_abstractmethoderror(void)
719 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
723 /* exceptions_throw_classcircularityerror **************************************
725 Generates and throws a java.lang.ClassCircularityError for the
729 c....the class in which the error was found
731 *******************************************************************************/
733 void exceptions_throw_classcircularityerror(classinfo *c)
735 exceptions_throw_utf_utf(utf_java_lang_ClassCircularityError, c->name);
739 /* exceptions_throw_classformaterror *******************************************
741 Generates and throws a java.lang.ClassFormatError for the VM.
744 c............the class in which the error was found
745 message......UTF-8 format string
747 *******************************************************************************/
749 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
756 /* calculate message length */
761 msglen += utf_bytes(c->name) + strlen(" (");
763 va_start(ap, message);
764 msglen += get_variable_message_length(message, ap);
768 msglen += strlen(")");
770 msglen += strlen("0");
772 /* allocate a buffer */
774 msg = MNEW(char, msglen);
776 /* print message into allocated buffer */
779 utf_copy_classname(msg, c->name);
783 va_start(ap, message);
784 vsprintf(msg + strlen(msg), message, ap);
790 u = utf_new_char(msg);
794 MFREE(msg, char, msglen);
796 /* throw exception */
798 exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
802 /* exceptions_throw_classnotfoundexception *************************************
804 Generates and throws a java.lang.ClassNotFoundException for the
808 name.........name of the class not found as a utf *
810 *******************************************************************************/
812 void exceptions_throw_classnotfoundexception(utf *name)
814 exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
818 /* exceptions_throw_noclassdeffounderror ***************************************
820 Generates and throws a java.lang.NoClassDefFoundError.
823 name.........name of the class not found as a utf *
825 *******************************************************************************/
827 void exceptions_throw_noclassdeffounderror(utf *name)
829 exceptions_throw_utf_utf(utf_java_lang_NoClassDefFoundError, name);
833 /* exceptions_throw_noclassdeffounderror_cause *********************************
835 Generates and throws a java.lang.NoClassDefFoundError with the
838 *******************************************************************************/
840 void exceptions_throw_noclassdeffounderror_cause(java_handle_t *cause)
842 exceptions_throw_utf_cause(utf_java_lang_NoClassDefFoundError, cause);
846 /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
848 Generates and throws a java.lang.NoClassDefFoundError with a
852 name.........name of the class not found as a utf *
854 *******************************************************************************/
856 void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
862 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
863 utf_bytes(name) + strlen(")") + strlen("0");
865 msg = MNEW(char, msglen);
867 utf_copy_classname(msg, c->name);
868 strcat(msg, " (wrong name: ");
869 utf_cat_classname(msg, name);
872 u = utf_new_char(msg);
874 MFREE(msg, char, msglen);
876 exceptions_throw_noclassdeffounderror(u);
880 /* exceptions_throw_exceptionininitializererror ********************************
882 Generates and throws a java.lang.ExceptionInInitializerError for
886 cause......cause exception object
888 *******************************************************************************/
890 void exceptions_throw_exceptionininitializererror(java_handle_t *cause)
892 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
897 /* exceptions_throw_incompatibleclasschangeerror *******************************
899 Generates and throws a java.lang.IncompatibleClassChangeError for
903 message......UTF-8 message format string
905 *******************************************************************************/
907 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
913 /* calculate exception message length */
915 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
917 /* allocate memory */
919 msg = MNEW(char, msglen);
921 utf_copy_classname(msg, c->name);
922 strcat(msg, message);
924 u = utf_new_char(msg);
928 MFREE(msg, char, msglen);
930 /* throw exception */
932 exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
936 /* exceptions_throw_instantiationerror *****************************************
938 Generates and throws a java.lang.InstantiationError for the VM.
940 *******************************************************************************/
942 void exceptions_throw_instantiationerror(classinfo *c)
944 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
948 /* exceptions_throw_internalerror **********************************************
950 Generates and throws a java.lang.InternalError for the VM.
953 message......UTF-8 message format string
955 *******************************************************************************/
957 void exceptions_throw_internalerror(const char *message, ...)
964 /* calculate exception message length */
966 va_start(ap, message);
967 msglen = get_variable_message_length(message, ap);
970 /* allocate memory */
972 msg = MNEW(char, msglen);
974 /* generate message */
976 va_start(ap, message);
977 vsprintf(msg, message, ap);
980 u = utf_new_char(msg);
984 MFREE(msg, char, msglen);
986 /* throw exception */
988 exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
992 /* exceptions_throw_linkageerror ***********************************************
994 Generates and throws java.lang.LinkageError with an error message.
997 message......UTF-8 message
998 c............class related to the error. If this is != NULL
999 the name of c is appended to the error message.
1001 *******************************************************************************/
1003 void exceptions_throw_linkageerror(const char *message, classinfo *c)
1009 /* calculate exception message length */
1011 len = strlen(message) + 1;
1014 len += utf_bytes(c->name);
1016 /* allocate memory */
1018 msg = MNEW(char, len);
1020 /* generate message */
1022 strcpy(msg, message);
1025 utf_cat_classname(msg, c->name);
1027 u = utf_new_char(msg);
1031 MFREE(msg, char, len);
1033 exceptions_throw_utf_utf(utf_java_lang_LinkageError, u);
1037 /* exceptions_throw_nosuchfielderror *******************************************
1039 Generates and throws a java.lang.NoSuchFieldError with an error
1043 c............class in which the field was not found
1044 name.........name of the field
1046 *******************************************************************************/
1048 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
1054 /* calculate exception message length */
1056 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
1058 /* allocate memory */
1060 msg = MNEW(char, msglen);
1062 /* generate message */
1064 utf_copy_classname(msg, c->name);
1068 u = utf_new_char(msg);
1072 MFREE(msg, char, msglen);
1074 exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
1078 /* exceptions_throw_nosuchmethoderror ******************************************
1080 Generates and throws a java.lang.NoSuchMethodError with an error
1084 c............class in which the method was not found
1085 name.........name of the method
1086 desc.........descriptor of the method
1088 *******************************************************************************/
1090 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
1096 /* calculate exception message length */
1098 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
1099 utf_bytes(desc) + strlen("0");
1101 /* allocate memory */
1103 msg = MNEW(char, msglen);
1105 /* generate message */
1107 utf_copy_classname(msg, c->name);
1112 u = utf_new_char(msg);
1116 MFREE(msg, char, msglen);
1118 #if defined(ENABLE_JAVASE)
1119 exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
1121 exceptions_throw_utf_utf(utf_java_lang_Error, u);
1126 /* exceptions_throw_outofmemoryerror *******************************************
1128 Generates and throws an java.lang.OutOfMemoryError for the VM.
1130 *******************************************************************************/
1132 void exceptions_throw_outofmemoryerror(void)
1134 exceptions_throw_utf(utf_java_lang_OutOfMemoryError);
1138 /* exceptions_throw_unsatisfiedlinkerror ***************************************
1140 Generates and throws a java.lang.UnsatisfiedLinkError for the
1144 name......UTF-8 name string
1146 *******************************************************************************/
1148 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1150 #if defined(ENABLE_JAVASE)
1151 exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1153 exceptions_throw_utf_utf(utf_java_lang_Error, name);
1158 /* exceptions_throw_unsupportedclassversionerror *******************************
1160 Generates and throws a java.lang.UnsupportedClassVersionError for
1164 c............class in which the method was not found
1165 message......UTF-8 format string
1167 *******************************************************************************/
1169 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1175 /* calculate exception message length */
1178 utf_bytes(c->name) +
1179 strlen(" (Unsupported major.minor version 00.0)") +
1182 /* allocate memory */
1184 msg = MNEW(char, msglen);
1186 /* generate message */
1188 utf_copy_classname(msg, c->name);
1189 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1192 u = utf_new_char(msg);
1196 MFREE(msg, char, msglen);
1198 /* throw exception */
1200 exceptions_throw_utf_utf(utf_java_lang_UnsupportedClassVersionError, u);
1204 /* exceptions_throw_verifyerror ************************************************
1206 Generates and throws a java.lang.VerifyError for the JIT compiler.
1209 m............method in which the error was found
1210 message......UTF-8 format string
1212 *******************************************************************************/
1214 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1221 /* calculate exception message length */
1227 strlen("(class: ") + utf_bytes(m->clazz->name) +
1228 strlen(", method: ") + utf_bytes(m->name) +
1229 strlen(" signature: ") + utf_bytes(m->descriptor) +
1230 strlen(") ") + strlen("0");
1232 va_start(ap, message);
1233 msglen += get_variable_message_length(message, ap);
1236 /* allocate memory */
1238 msg = MNEW(char, msglen);
1240 /* generate message */
1243 strcpy(msg, "(class: ");
1244 utf_cat_classname(msg, m->clazz->name);
1245 strcat(msg, ", method: ");
1246 utf_cat(msg, m->name);
1247 strcat(msg, " signature: ");
1248 utf_cat(msg, m->descriptor);
1252 va_start(ap, message);
1253 vsprintf(msg + strlen(msg), message, ap);
1256 u = utf_new_char(msg);
1260 MFREE(msg, char, msglen);
1262 /* throw exception */
1264 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1268 /* exceptions_throw_verifyerror_for_stack **************************************
1270 throws a java.lang.VerifyError for an invalid stack slot type
1273 m............method in which the error was found
1274 type.........the expected type
1277 an exception pointer (in any case -- either it is the newly created
1278 exception, or an exception thrown while trying to create it).
1280 *******************************************************************************/
1282 void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
1288 /* calculate exception message length */
1293 msglen = strlen("(class: ") + utf_bytes(m->clazz->name) +
1294 strlen(", method: ") + utf_bytes(m->name) +
1295 strlen(" signature: ") + utf_bytes(m->descriptor) +
1296 strlen(") Expecting to find longest-------typename on stack")
1299 /* allocate memory */
1301 msg = MNEW(char, msglen);
1303 /* generate message */
1306 strcpy(msg, "(class: ");
1307 utf_cat_classname(msg, m->clazz->name);
1308 strcat(msg, ", method: ");
1309 utf_cat(msg, m->name);
1310 strcat(msg, " signature: ");
1311 utf_cat(msg, m->descriptor);
1318 strcat(msg, "Expecting to find ");
1323 case TYPE_INT: name = "integer"; break;
1324 case TYPE_LNG: name = "long"; break;
1325 case TYPE_FLT: name = "float"; break;
1326 case TYPE_DBL: name = "double"; break;
1327 case TYPE_ADR: name = "object/array"; break;
1328 case TYPE_RET: name = "returnAddress"; break;
1329 default: name = "<INVALID>"; assert(0); break;
1333 strcat(msg, " on stack");
1335 u = utf_new_char(msg);
1339 MFREE(msg, char, msglen);
1341 /* throw exception */
1343 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1347 /* exceptions_new_arithmeticexception ******************************************
1349 Generates a java.lang.ArithmeticException for the JIT compiler.
1351 *******************************************************************************/
1353 java_handle_t *exceptions_new_arithmeticexception(void)
1357 o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
1358 utf_division_by_zero);
1364 /* exceptions_new_arrayindexoutofboundsexception *******************************
1366 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1369 *******************************************************************************/
1371 java_handle_t *exceptions_new_arrayindexoutofboundsexception(s4 index)
1377 /* convert the index into a String, like Sun does */
1379 m = class_resolveclassmethod(class_java_lang_String,
1380 utf_new_char("valueOf"),
1381 utf_new_char("(I)Ljava/lang/String;"),
1382 class_java_lang_Object,
1386 return exceptions_get_exception();
1388 s = vm_call_method(m, NULL, index);
1391 return exceptions_get_exception();
1393 o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1397 return exceptions_get_exception();
1403 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1405 Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1408 *******************************************************************************/
1410 void exceptions_throw_arrayindexoutofboundsexception(void)
1412 exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1416 /* exceptions_throw_arraystoreexception ****************************************
1418 Generates and throws a java.lang.ArrayStoreException for the VM.
1420 *******************************************************************************/
1422 void exceptions_throw_arraystoreexception(void)
1424 exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1428 /* exceptions_new_classcastexception *******************************************
1430 Generates a java.lang.ClassCastException for the JIT compiler.
1432 *******************************************************************************/
1434 java_handle_t *exceptions_new_classcastexception(java_handle_t *o)
1440 LLNI_class_get(o, c);
1442 classname = c->name;
1444 e = exceptions_new_utf_utf(utf_java_lang_ClassCastException, classname);
1450 /* exceptions_throw_clonenotsupportedexception *********************************
1452 Generates and throws a java.lang.CloneNotSupportedException for the
1455 *******************************************************************************/
1457 void exceptions_throw_clonenotsupportedexception(void)
1459 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1463 /* exceptions_throw_illegalaccessexception *************************************
1465 Generates and throws a java.lang.IllegalAccessException for the VM.
1467 *******************************************************************************/
1469 void exceptions_throw_illegalaccessexception(utf *message)
1471 exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
1475 /* exceptions_throw_illegalargumentexception ***********************************
1477 Generates and throws a java.lang.IllegalArgumentException for the
1480 *******************************************************************************/
1482 void exceptions_throw_illegalargumentexception(void)
1484 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1488 /* exceptions_throw_illegalmonitorstateexception *******************************
1490 Generates and throws a java.lang.IllegalMonitorStateException for
1493 *******************************************************************************/
1495 void exceptions_throw_illegalmonitorstateexception(void)
1497 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1501 /* exceptions_throw_instantiationexception *************************************
1503 Generates and throws a java.lang.InstantiationException for the VM.
1505 *******************************************************************************/
1507 void exceptions_throw_instantiationexception(classinfo *c)
1509 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1513 /* exceptions_throw_interruptedexception ***************************************
1515 Generates and throws a java.lang.InterruptedException for the VM.
1517 *******************************************************************************/
1519 void exceptions_throw_interruptedexception(void)
1521 exceptions_throw_utf(utf_java_lang_InterruptedException);
1525 /* exceptions_throw_invocationtargetexception **********************************
1527 Generates and throws a java.lang.reflect.InvocationTargetException
1531 cause......cause exception object
1533 *******************************************************************************/
1535 void exceptions_throw_invocationtargetexception(java_handle_t *cause)
1537 exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1542 /* exceptions_throw_negativearraysizeexception *********************************
1544 Generates and throws a java.lang.NegativeArraySizeException for the
1547 *******************************************************************************/
1549 void exceptions_throw_negativearraysizeexception(void)
1551 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1555 /* exceptions_new_nullpointerexception *****************************************
1557 Generates a java.lang.NullPointerException for the VM system.
1559 *******************************************************************************/
1561 java_handle_t *exceptions_new_nullpointerexception(void)
1565 o = exceptions_new_utf(utf_java_lang_NullPointerException);
1571 /* exceptions_throw_nullpointerexception ***************************************
1573 Generates a java.lang.NullPointerException for the VM system and
1574 throw it in the VM system.
1576 *******************************************************************************/
1578 void exceptions_throw_nullpointerexception(void)
1580 exceptions_throw_utf(utf_java_lang_NullPointerException);
1584 /* exceptions_throw_privilegedactionexception **********************************
1586 Generates and throws a java.security.PrivilegedActionException.
1588 *******************************************************************************/
1590 void exceptions_throw_privilegedactionexception(java_handle_t *exception)
1592 exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
1597 /* exceptions_throw_stringindexoutofboundsexception ****************************
1599 Generates and throws a java.lang.StringIndexOutOfBoundsException
1602 *******************************************************************************/
1604 void exceptions_throw_stringindexoutofboundsexception(void)
1606 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1610 /* exceptions_fillinstacktrace *************************************************
1612 Calls the fillInStackTrace-method of the currently thrown
1615 *******************************************************************************/
1617 java_handle_t *exceptions_fillinstacktrace(void)
1625 o = exceptions_get_and_clear_exception();
1629 /* resolve methodinfo pointer from exception object */
1631 LLNI_class_get(o, c);
1633 #if defined(ENABLE_JAVASE)
1634 m = class_resolvemethod(c,
1635 utf_fillInStackTrace,
1636 utf_void__java_lang_Throwable);
1637 #elif defined(ENABLE_JAVAME_CLDC1_1)
1638 m = class_resolvemethod(c,
1639 utf_fillInStackTrace,
1642 #error IMPLEMENT ME!
1647 (void) vm_call_method(m, o);
1649 /* return exception object */
1655 /* exceptions_handle_exception *************************************************
1657 Try to find an exception handler for the given exception and return it.
1658 If no handler is found, exit the monitor of the method (if any)
1662 xptr.........the exception object
1663 xpc..........PC of where the exception was thrown
1664 pv...........Procedure Value of the current method
1665 sp...........current stack pointer
1668 the address of the first matching exception handler, or
1669 NULL if no handler was found
1671 *******************************************************************************/
1673 #if defined(ENABLE_JIT)
1674 void *exceptions_handle_exception(java_object_t *xptro, void *xpc, void *pv, void *sp)
1676 stackframeinfo_t sfi;
1677 java_handle_t *xptr;
1680 exceptiontable_t *et;
1681 exceptiontable_entry_t *ete;
1683 classref_or_classinfo cr;
1685 #if defined(ENABLE_THREADS)
1691 /* Addresses are 31 bit integers */
1692 # define ADDR_MASK(x) (void *) ((uintptr_t) (x) & 0x7FFFFFFF)
1694 # define ADDR_MASK(x) (x)
1697 xptr = LLNI_WRAP(xptro);
1698 xpc = ADDR_MASK(xpc);
1700 /* Fill and add a stackframeinfo (XPC is equal to RA). */
1702 stacktrace_stackframeinfo_add(&sfi, pv, sp, xpc, xpc);
1706 /* Get the codeinfo for the current method. */
1708 code = code_get_codeinfo_for_pv(pv);
1710 /* Get the methodinfo pointer from the codeinfo pointer. For
1711 asm_vm_call_method the codeinfo pointer is NULL and we simply
1712 can return the proper exception handler. */
1715 result = (void *) (uintptr_t) &asm_vm_call_method_exception_handler;
1716 goto exceptions_handle_exception_return;
1721 #if !defined(NDEBUG)
1722 /* print exception trace */
1724 if (opt_TraceExceptions)
1725 trace_exception(LLNI_DIRECT(xptr), m, xpc);
1727 # if defined(ENABLE_VMLOG)
1728 vmlog_cacao_throw(xptr);
1732 /* Get the exception table. */
1734 et = code->exceptiontable;
1737 /* Iterate over all exception table entries. */
1741 for (i = 0; i < et->length; i++, ete++) {
1742 /* is the xpc is the current catch range */
1744 if ((ADDR_MASK(ete->startpc) <= xpc) && (xpc < ADDR_MASK(ete->endpc))) {
1745 cr = ete->catchtype;
1747 /* NULL catches everything */
1749 if (cr.any == NULL) {
1750 #if !defined(NDEBUG)
1751 /* Print stacktrace of exception when caught. */
1753 # if defined(ENABLE_VMLOG)
1754 vmlog_cacao_catch(xptr);
1757 if (opt_TraceExceptions) {
1758 exceptions_print_exception(xptr);
1759 stacktrace_print_exception(xptr);
1763 result = ete->handlerpc;
1764 goto exceptions_handle_exception_return;
1767 /* resolve or load/link the exception class */
1769 if (IS_CLASSREF(cr)) {
1770 /* The exception class reference is unresolved. */
1771 /* We have to do _eager_ resolving here. While the
1772 class of the exception object is guaranteed to be
1773 loaded, it may well have been loaded by a different
1774 loader than the defining loader of m's class, which
1775 is the one we must use to resolve the catch
1776 class. Thus lazy resolving might fail, even if the
1777 result of the resolution would be an already loaded
1780 c = resolve_classref_eager(cr.ref);
1783 /* Exception resolving the exception class, argh! */
1784 goto exceptions_handle_exception_return;
1787 /* Ok, we resolved it. Enter it in the table, so we
1788 don't have to do this again. */
1789 /* XXX this write should be atomic. Is it? */
1791 ete->catchtype.cls = c;
1796 /* XXX I don't think this case can ever happen. -Edwin */
1797 if (!(c->state & CLASS_LOADED))
1798 /* use the methods' classloader */
1799 if (!load_class_from_classloader(c->name,
1800 m->clazz->classloader))
1801 goto exceptions_handle_exception_return;
1803 /* XXX I think, if it is not linked, we can be sure
1804 that the exception object is no (indirect) instance
1805 of it, no? -Edwin */
1806 if (!(c->state & CLASS_LINKED))
1808 goto exceptions_handle_exception_return;
1811 /* is the thrown exception an instance of the catch class? */
1813 if (builtin_instanceof(xptr, c)) {
1814 #if !defined(NDEBUG)
1815 /* Print stacktrace of exception when caught. */
1817 # if defined(ENABLE_VMLOG)
1818 vmlog_cacao_catch(xptr);
1821 if (opt_TraceExceptions) {
1822 exceptions_print_exception(xptr);
1823 stacktrace_print_exception(xptr);
1827 result = ete->handlerpc;
1828 goto exceptions_handle_exception_return;
1834 #if defined(ENABLE_THREADS)
1835 /* Is this method realization synchronized? */
1837 if (code_is_synchronized(code)) {
1838 /* Get synchronization object. */
1840 o = *((java_object_t **) (((uintptr_t) sp) + code->synchronizedoffset));
1844 lock_monitor_exit(LLNI_QUICKWRAP(o));
1848 /* none of the exceptions catch this one */
1850 #if !defined(NDEBUG)
1851 # if defined(ENABLE_VMLOG)
1852 vmlog_cacao_unwnd_method(m);
1855 # if defined(ENABLE_DEBUG_FILTER)
1856 if (show_filters_test_verbosecall_exit(m)) {
1859 /* outdent the log message */
1861 if (opt_verbosecall) {
1862 if (TRACEJAVACALLINDENT)
1863 TRACEJAVACALLINDENT--;
1865 log_text("exceptions_handle_exception: WARNING: unmatched unindent");
1868 # if defined(ENABLE_DEBUG_FILTER)
1871 #endif /* !defined(NDEBUG) */
1875 exceptions_handle_exception_return:
1877 /* Remove the stackframeinfo. */
1879 stacktrace_stackframeinfo_remove(&sfi);
1883 #endif /* defined(ENABLE_JIT) */
1886 /* exceptions_print_exception **************************************************
1888 Prints an exception, the detail message and the cause, if
1889 available, with CACAO internal functions to stdout.
1891 *******************************************************************************/
1893 void exceptions_print_exception(java_handle_t *xptr)
1895 java_lang_Throwable jlt(xptr);
1897 if (jlt.is_null()) {
1902 #if defined(ENABLE_JAVASE)
1903 java_lang_Throwable jltcause(jlt.get_cause());
1906 /* print the root exception */
1908 classinfo* c = jlt.get_Class();
1909 utf_display_printable_ascii_classname(c->name);
1911 java_lang_String jls(jlt.get_detailMessage());
1913 if (!jls.is_null()) {
1914 utf* u = javastring_toutf(jls.get_handle(), false);
1917 utf_display_printable_ascii(u);
1922 #if defined(ENABLE_JAVASE)
1923 /* print the cause if available */
1925 // FIXME cause != t compare with operator override.
1926 if ((!jltcause.is_null()) && (jltcause.get_handle() != jlt.get_handle())) {
1927 printf("Caused by: ");
1929 c = jltcause.get_Class();
1930 utf_display_printable_ascii_classname(c->name);
1932 java_lang_String jlscause(jlt.get_detailMessage());
1934 if (jlscause.get_handle() != NULL) {
1935 utf* u = javastring_toutf(jlscause.get_handle(), false);
1938 utf_display_printable_ascii(u);
1947 /* exceptions_print_current_exception ******************************************
1949 Prints the current pending exception, the detail message and the
1950 cause, if available, with CACAO internal functions to stdout.
1952 *******************************************************************************/
1954 void exceptions_print_current_exception(void)
1958 o = exceptions_get_exception();
1960 exceptions_print_exception(o);
1964 /* exceptions_print_stacktrace *************************************************
1966 Prints a pending exception with Throwable.printStackTrace(). If
1967 there happens an exception during printStackTrace(), we print the
1968 thrown exception and the original one.
1970 NOTE: This function calls Java code.
1972 *******************************************************************************/
1974 void exceptions_print_stacktrace(void)
1981 #if defined(ENABLE_THREADS)
1983 java_lang_Thread *to;
1986 /* Get and clear exception because we are calling Java code
1989 e = exceptions_get_and_clear_exception();
1995 /* FIXME Enable me. */
1996 if (builtin_instanceof(e, class_java_lang_ThreadDeath)) {
1997 /* Don't print anything if we are being killed. */
2002 /* Get the exception class. */
2004 LLNI_class_get(e, c);
2006 /* Find the printStackTrace() method. */
2008 m = class_resolveclassmethod(c,
2009 utf_printStackTrace,
2011 class_java_lang_Object,
2015 vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
2017 /* Print message. */
2019 fprintf(stderr, "Exception ");
2021 #if defined(ENABLE_THREADS)
2022 /* Print thread name. We get the thread here explicitly as we
2023 need it afterwards. */
2025 t = thread_get_current();
2026 to = (java_lang_Thread *) thread_get_object(t);
2029 fprintf(stderr, "in thread \"");
2030 thread_fprint_name(t, stderr);
2031 fprintf(stderr, "\" ");
2035 /* Print the stacktrace. */
2037 if (builtin_instanceof(e, class_java_lang_Throwable)) {
2038 (void) vm_call_method(m, e);
2040 /* If this happens we are EXTREMLY out of memory or have a
2041 serious problem while printStackTrace. But may be
2042 another exception, so print it. */
2044 ne = exceptions_get_exception();
2047 fprintf(stderr, "Exception while printStackTrace(): ");
2049 /* Print the current exception. */
2051 exceptions_print_exception(ne);
2052 stacktrace_print_exception(ne);
2054 /* Now print the original exception. */
2056 fprintf(stderr, "Original exception was: ");
2057 exceptions_print_exception(e);
2058 stacktrace_print_exception(e);
2062 fprintf(stderr, ". Uncaught exception of type ");
2063 #if !defined(NDEBUG)
2064 /* FIXME This prints to stdout. */
2067 fprintf(stderr, "UNKNOWN");
2069 fprintf(stderr, ".");
2080 * These are local overrides for various environment variables in Emacs.
2081 * Please do not remove this and leave it at the end of the file, where
2082 * Emacs will automagically detect them.
2083 * ---------------------------------------------------------------------
2086 * indent-tabs-mode: t
2090 * vim:noexpandtab:sw=4:ts=4: