1 /* src/vm/exceptions.c - exception related functions
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, 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., 51 Franklin Street, Fifth Floor, Boston, MA
41 #include "mm/memory.h"
43 #include "native/jni.h"
44 #include "native/llni.h"
45 #include "native/native.h"
47 #include "native/include/java_lang_String.h"
48 #include "native/include/java_lang_Throwable.h"
50 #include "threads/lock-common.h"
51 #include "threads/threads-common.h"
53 #include "toolbox/util.h"
55 #include "vm/builtin.h"
56 #include "vm/exceptions.h"
57 #include "vm/global.h"
58 #include "vm/stringlocal.h"
61 #include "vm/jit/asmpart.h"
62 #include "vm/jit/jit.h"
63 #include "vm/jit/methodheader.h"
64 #include "vm/jit/patcher-common.h"
65 #include "vm/jit/show.h"
66 #include "vm/jit/stacktrace.h"
67 #include "vm/jit/trace.h"
69 #include "vmcore/class.h"
70 #include "vmcore/loader.h"
71 #include "vmcore/method.h"
72 #include "vmcore/options.h"
73 #include "vmcore/system.h"
75 #if defined(ENABLE_VMLOG)
76 #include <vmlog_cacao.h>
80 /* for raising exceptions from native methods *********************************/
82 #if !defined(ENABLE_THREADS)
83 java_object_t *_no_threads_exceptionptr = NULL;
87 /* exceptions_init *************************************************************
89 Initialize the exceptions subsystem.
91 *******************************************************************************/
93 void exceptions_init(void)
95 #if !(defined(__ARM__) && defined(__LINUX__))
96 /* On arm-linux the first memory page can't be mmap'ed, as it
97 contains the exception vectors. */
101 /* mmap a memory page at address 0x0, so our hardware-exceptions
104 pagesize = system_getpagesize();
106 (void) system_mmap_anonymous(NULL, pagesize, PROT_NONE, MAP_PRIVATE | MAP_FIXED);
109 /* check if we get into trouble with our hardware-exceptions */
111 if (OFFSET(java_bytearray_t, data) <= EXCEPTION_HARDWARE_LARGEST)
112 vm_abort("signal_init: array-data offset is less or equal the maximum hardware-exception displacement: %d <= %d", OFFSET(java_bytearray_t, data), EXCEPTION_HARDWARE_LARGEST);
116 /* exceptions_get_exception ****************************************************
118 Returns the current exception pointer of the current thread.
120 *******************************************************************************/
122 java_handle_t *exceptions_get_exception(void)
126 #if defined(ENABLE_THREADS)
132 /* Get the exception. */
136 #if defined(ENABLE_THREADS)
137 o = t->_exceptionptr;
139 o = _no_threads_exceptionptr;
146 /* Return the exception. */
152 /* exceptions_set_exception ****************************************************
154 Sets the exception pointer of the current thread.
156 *******************************************************************************/
158 void exceptions_set_exception(java_handle_t *e)
163 #if defined(ENABLE_THREADS)
169 /* Set the exception. */
176 if (opt_DebugExceptions) {
177 printf("[exceptions_set_exception : t=%p, o=%p, class=",
178 (void *) t, (void *) o);
179 class_print(o->vftbl->class);
184 #if defined(ENABLE_THREADS)
185 t->_exceptionptr = o;
187 _no_threads_exceptionptr = o;
194 /* exceptions_clear_exception **************************************************
196 Clears the current exception pointer of the current thread.
198 *******************************************************************************/
200 void exceptions_clear_exception(void)
204 #if defined(ENABLE_THREADS)
210 /* Set the exception. */
213 if (opt_DebugExceptions) {
214 printf("[exceptions_clear_exception: t=%p]\n", (void *) t);
218 #if defined(ENABLE_THREADS)
219 t->_exceptionptr = NULL;
221 _no_threads_exceptionptr = NULL;
226 /* exceptions_get_and_clear_exception ******************************************
228 Gets the exception pointer of the current thread and clears it.
229 This function may return NULL.
231 *******************************************************************************/
233 java_handle_t *exceptions_get_and_clear_exception(void)
237 /* Get the exception... */
239 o = exceptions_get_exception();
241 /* ...and clear the exception if it is set. */
244 exceptions_clear_exception();
246 /* return the exception */
252 /* exceptions_abort ************************************************************
254 Prints exception to be thrown and aborts.
257 classname....class name
258 message......exception message
260 *******************************************************************************/
262 static void exceptions_abort(utf *classname, utf *message)
264 log_println("exception thrown while VM is initializing: ");
267 utf_display_printable_ascii_classname(classname);
269 if (message != NULL) {
271 utf_display_printable_ascii_classname(message);
276 vm_abort("Aborting...");
280 /* exceptions_new_utf **********************************************************
282 Creates an exception object with the given name and initalizes it.
285 classname....class name in UTF-8
287 *******************************************************************************/
289 static java_handle_t *exceptions_new_utf(utf *classname)
295 exceptions_abort(classname, NULL);
297 c = load_class_bootstrap(classname);
300 return exceptions_get_exception();
302 o = native_new_and_init(c);
305 return exceptions_get_exception();
311 /* exceptions_throw_utf ********************************************************
313 Creates an exception object with the given name, initalizes and
317 classname....class name in UTF-8
319 *******************************************************************************/
321 static void exceptions_throw_utf(utf *classname)
325 o = exceptions_new_utf(classname);
330 exceptions_set_exception(o);
334 /* exceptions_throw_utf_throwable **********************************************
336 Creates an exception object with the given name and initalizes it
337 with the given java/lang/Throwable exception.
340 classname....class name in UTF-8
341 cause........the given Throwable
343 *******************************************************************************/
345 static void exceptions_throw_utf_throwable(utf *classname,
346 java_handle_t *cause)
351 java_lang_Throwable *object;
354 exceptions_abort(classname, NULL);
356 object = (java_lang_Throwable *) cause;
358 c = load_class_bootstrap(classname);
370 /* call initializer */
372 m = class_resolveclassmethod(c,
374 utf_java_lang_Throwable__void,
381 (void) vm_call_method(m, o, cause);
383 exceptions_set_exception(o);
387 /* exceptions_throw_utf_exception **********************************************
389 Creates an exception object with the given name and initalizes it
390 with the given java/lang/Exception exception.
393 classname....class name in UTF-8
394 exception....the given Exception
396 *******************************************************************************/
398 static void exceptions_throw_utf_exception(utf *classname,
399 java_handle_t *exception)
406 exceptions_abort(classname, NULL);
408 c = load_class_bootstrap(classname);
420 /* call initializer */
422 m = class_resolveclassmethod(c,
424 utf_java_lang_Exception__V,
431 (void) vm_call_method(m, o, exception);
433 exceptions_set_exception(o);
437 /* exceptions_throw_utf_cause **************************************************
439 Creates an exception object with the given name and initalizes it
440 with the given java/lang/Throwable exception with initCause.
443 classname....class name in UTF-8
444 cause........the given Throwable
446 *******************************************************************************/
448 static void exceptions_throw_utf_cause(utf *classname, java_handle_t *cause)
454 java_lang_Throwable *object;
457 exceptions_abort(classname, NULL);
459 object = (java_lang_Throwable *) cause;
461 c = load_class_bootstrap(classname);
473 /* call initializer */
475 m = class_resolveclassmethod(c,
477 utf_java_lang_String__void,
484 LLNI_field_get_ref(object, detailMessage, s);
486 (void) vm_call_method(m, o, s);
490 m = class_resolveclassmethod(c,
492 utf_java_lang_Throwable__java_lang_Throwable,
499 (void) vm_call_method(m, o, cause);
501 exceptions_set_exception(o);
505 /* exceptions_new_utf_javastring ***********************************************
507 Creates an exception object with the given name and initalizes it
508 with the given java/lang/String message.
511 classname....class name in UTF-8
512 message......the message as a java.lang.String
515 an exception pointer (in any case -- either it is the newly created
516 exception, or an exception thrown while trying to create it).
518 *******************************************************************************/
520 static java_handle_t *exceptions_new_utf_javastring(utf *classname,
521 java_handle_t *message)
527 exceptions_abort(classname, NULL);
529 c = load_class_bootstrap(classname);
532 return exceptions_get_exception();
534 o = native_new_and_init_string(c, message);
537 return exceptions_get_exception();
543 /* exceptions_new_utf_utf ******************************************************
545 Creates an exception object with the given name and initalizes it
546 with the given utf message.
549 classname....class name in UTF-8
550 message......the message as an utf *
553 an exception pointer (in any case -- either it is the newly created
554 exception, or an exception thrown while trying to create it).
556 *******************************************************************************/
558 static java_handle_t *exceptions_new_utf_utf(utf *classname, utf *message)
565 exceptions_abort(classname, message);
567 c = load_class_bootstrap(classname);
570 return exceptions_get_exception();
572 s = javastring_new(message);
575 return exceptions_get_exception();
577 o = native_new_and_init_string(c, s);
580 return exceptions_get_exception();
586 /* exceptions_throw_utf_utf ****************************************************
588 Creates an exception object with the given name, initalizes and
589 throws it with the given utf message.
592 classname....class name in UTF-8
593 message......the message as an utf *
595 *******************************************************************************/
597 static void exceptions_throw_utf_utf(utf *classname, utf *message)
601 o = exceptions_new_utf_utf(classname, message);
603 exceptions_set_exception(o);
607 /* exceptions_new_abstractmethoderror ****************************************
609 Generates a java.lang.AbstractMethodError for the VM.
611 *******************************************************************************/
613 java_handle_t *exceptions_new_abstractmethoderror(void)
617 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
623 /* exceptions_new_error ********************************************************
625 Generates a java.lang.Error for the VM.
627 *******************************************************************************/
629 #if defined(ENABLE_JAVAME_CLDC1_1)
630 static java_handle_t *exceptions_new_error(utf *message)
634 o = exceptions_new_utf_utf(utf_java_lang_Error, message);
641 /* exceptions_asm_new_abstractmethoderror **************************************
643 Generates a java.lang.AbstractMethodError for
644 asm_abstractmethoderror.
646 *******************************************************************************/
648 java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
650 stackframeinfo_t sfi;
654 /* Fill and add a stackframeinfo (XPC is equal to RA). */
656 stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra);
658 /* create the exception */
660 #if defined(ENABLE_JAVASE)
661 e = exceptions_new_abstractmethoderror();
663 e = exceptions_new_error(utf_java_lang_AbstractMethodError);
666 /* Remove the stackframeinfo. */
668 stacktrace_stackframeinfo_remove(&sfi);
670 /* unwrap the exception */
671 /* ATTENTION: do the this _after_ the stackframeinfo was removed */
679 /* exceptions_new_arraystoreexception ******************************************
681 Generates a java.lang.ArrayStoreException for the VM.
683 *******************************************************************************/
685 java_handle_t *exceptions_new_arraystoreexception(void)
689 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
695 /* exceptions_throw_abstractmethoderror ****************************************
697 Generates and throws a java.lang.AbstractMethodError for the VM.
699 *******************************************************************************/
701 void exceptions_throw_abstractmethoderror(void)
703 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
707 /* exceptions_throw_classcircularityerror **************************************
709 Generates and throws a java.lang.ClassCircularityError for the
713 c....the class in which the error was found
715 *******************************************************************************/
717 void exceptions_throw_classcircularityerror(classinfo *c)
719 exceptions_throw_utf_utf(utf_java_lang_ClassCircularityError, c->name);
723 /* exceptions_throw_classformaterror *******************************************
725 Generates and throws a java.lang.ClassFormatError for the VM.
728 c............the class in which the error was found
729 message......UTF-8 format string
731 *******************************************************************************/
733 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
740 /* calculate message length */
745 msglen += utf_bytes(c->name) + strlen(" (");
747 va_start(ap, message);
748 msglen += get_variable_message_length(message, ap);
752 msglen += strlen(")");
754 msglen += strlen("0");
756 /* allocate a buffer */
758 msg = MNEW(char, msglen);
760 /* print message into allocated buffer */
763 utf_copy_classname(msg, c->name);
767 va_start(ap, message);
768 vsprintf(msg + strlen(msg), message, ap);
774 u = utf_new_char(msg);
778 MFREE(msg, char, msglen);
780 /* throw exception */
782 exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
786 /* exceptions_throw_classnotfoundexception *************************************
788 Generates and throws a java.lang.ClassNotFoundException for the
792 name.........name of the class not found as a utf *
794 *******************************************************************************/
796 void exceptions_throw_classnotfoundexception(utf *name)
798 exceptions_throw_utf_utf(utf_java_lang_ClassNotFoundException, name);
802 /* exceptions_throw_noclassdeffounderror ***************************************
804 Generates and throws a java.lang.NoClassDefFoundError.
807 name.........name of the class not found as a utf *
809 *******************************************************************************/
811 void exceptions_throw_noclassdeffounderror(utf *name)
813 exceptions_throw_utf_utf(utf_java_lang_NoClassDefFoundError, name);
817 /* exceptions_throw_noclassdeffounderror_cause *********************************
819 Generates and throws a java.lang.NoClassDefFoundError with the
822 *******************************************************************************/
824 void exceptions_throw_noclassdeffounderror_cause(java_handle_t *cause)
826 exceptions_throw_utf_cause(utf_java_lang_NoClassDefFoundError, cause);
830 /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
832 Generates and throws a java.lang.NoClassDefFoundError with a
836 name.........name of the class not found as a utf *
838 *******************************************************************************/
840 void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
846 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
847 utf_bytes(name) + strlen(")") + strlen("0");
849 msg = MNEW(char, msglen);
851 utf_copy_classname(msg, c->name);
852 strcat(msg, " (wrong name: ");
853 utf_cat_classname(msg, name);
856 u = utf_new_char(msg);
858 MFREE(msg, char, msglen);
860 exceptions_throw_noclassdeffounderror(u);
864 /* exceptions_throw_exceptionininitializererror ********************************
866 Generates and throws a java.lang.ExceptionInInitializerError for
870 cause......cause exception object
872 *******************************************************************************/
874 void exceptions_throw_exceptionininitializererror(java_handle_t *cause)
876 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
881 /* exceptions_throw_incompatibleclasschangeerror *******************************
883 Generates and throws a java.lang.IncompatibleClassChangeError for
887 message......UTF-8 message format string
889 *******************************************************************************/
891 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
897 /* calculate exception message length */
899 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
901 /* allocate memory */
903 msg = MNEW(char, msglen);
905 utf_copy_classname(msg, c->name);
906 strcat(msg, message);
908 u = utf_new_char(msg);
912 MFREE(msg, char, msglen);
914 /* throw exception */
916 exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
920 /* exceptions_throw_instantiationerror *****************************************
922 Generates and throws a java.lang.InstantiationError for the VM.
924 *******************************************************************************/
926 void exceptions_throw_instantiationerror(classinfo *c)
928 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
932 /* exceptions_throw_internalerror **********************************************
934 Generates and throws a java.lang.InternalError for the VM.
937 message......UTF-8 message format string
939 *******************************************************************************/
941 void exceptions_throw_internalerror(const char *message, ...)
948 /* calculate exception message length */
950 va_start(ap, message);
951 msglen = get_variable_message_length(message, ap);
954 /* allocate memory */
956 msg = MNEW(char, msglen);
958 /* generate message */
960 va_start(ap, message);
961 vsprintf(msg, message, ap);
964 u = utf_new_char(msg);
968 MFREE(msg, char, msglen);
970 /* throw exception */
972 exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
976 /* exceptions_throw_linkageerror ***********************************************
978 Generates and throws java.lang.LinkageError with an error message.
981 message......UTF-8 message
982 c............class related to the error. If this is != NULL
983 the name of c is appended to the error message.
985 *******************************************************************************/
987 void exceptions_throw_linkageerror(const char *message, classinfo *c)
993 /* calculate exception message length */
995 len = strlen(message) + 1;
998 len += utf_bytes(c->name);
1000 /* allocate memory */
1002 msg = MNEW(char, len);
1004 /* generate message */
1006 strcpy(msg, message);
1009 utf_cat_classname(msg, c->name);
1011 u = utf_new_char(msg);
1015 MFREE(msg, char, len);
1017 exceptions_throw_utf_utf(utf_java_lang_LinkageError, u);
1021 /* exceptions_throw_nosuchfielderror *******************************************
1023 Generates and throws a java.lang.NoSuchFieldError with an error
1027 c............class in which the field was not found
1028 name.........name of the field
1030 *******************************************************************************/
1032 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
1038 /* calculate exception message length */
1040 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
1042 /* allocate memory */
1044 msg = MNEW(char, msglen);
1046 /* generate message */
1048 utf_copy_classname(msg, c->name);
1052 u = utf_new_char(msg);
1056 MFREE(msg, char, msglen);
1058 exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
1062 /* exceptions_throw_nosuchmethoderror ******************************************
1064 Generates and throws a java.lang.NoSuchMethodError with an error
1068 c............class in which the method was not found
1069 name.........name of the method
1070 desc.........descriptor of the method
1072 *******************************************************************************/
1074 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
1080 /* calculate exception message length */
1082 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
1083 utf_bytes(desc) + strlen("0");
1085 /* allocate memory */
1087 msg = MNEW(char, msglen);
1089 /* generate message */
1091 utf_copy_classname(msg, c->name);
1096 u = utf_new_char(msg);
1100 MFREE(msg, char, msglen);
1102 #if defined(ENABLE_JAVASE)
1103 exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
1105 exceptions_throw_utf_utf(utf_java_lang_Error, u);
1110 /* exceptions_throw_outofmemoryerror *******************************************
1112 Generates and throws an java.lang.OutOfMemoryError for the VM.
1114 *******************************************************************************/
1116 void exceptions_throw_outofmemoryerror(void)
1118 exceptions_throw_utf(utf_java_lang_OutOfMemoryError);
1122 /* exceptions_throw_unsatisfiedlinkerror ***************************************
1124 Generates and throws a java.lang.UnsatisfiedLinkError for the
1128 name......UTF-8 name string
1130 *******************************************************************************/
1132 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1134 #if defined(ENABLE_JAVASE)
1135 exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1137 exceptions_throw_utf_utf(utf_java_lang_Error, name);
1142 /* exceptions_throw_unsupportedclassversionerror *******************************
1144 Generates and throws a java.lang.UnsupportedClassVersionError for
1148 c............class in which the method was not found
1149 message......UTF-8 format string
1151 *******************************************************************************/
1153 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1159 /* calculate exception message length */
1162 utf_bytes(c->name) +
1163 strlen(" (Unsupported major.minor version 00.0)") +
1166 /* allocate memory */
1168 msg = MNEW(char, msglen);
1170 /* generate message */
1172 utf_copy_classname(msg, c->name);
1173 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1176 u = utf_new_char(msg);
1180 MFREE(msg, char, msglen);
1182 /* throw exception */
1184 exceptions_throw_utf_utf(utf_java_lang_UnsupportedClassVersionError, u);
1188 /* exceptions_throw_verifyerror ************************************************
1190 Generates and throws a java.lang.VerifyError for the JIT compiler.
1193 m............method in which the error was found
1194 message......UTF-8 format string
1196 *******************************************************************************/
1198 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1205 /* calculate exception message length */
1211 strlen("(class: ") + utf_bytes(m->class->name) +
1212 strlen(", method: ") + utf_bytes(m->name) +
1213 strlen(" signature: ") + utf_bytes(m->descriptor) +
1214 strlen(") ") + strlen("0");
1216 va_start(ap, message);
1217 msglen += get_variable_message_length(message, ap);
1220 /* allocate memory */
1222 msg = MNEW(char, msglen);
1224 /* generate message */
1227 strcpy(msg, "(class: ");
1228 utf_cat_classname(msg, m->class->name);
1229 strcat(msg, ", method: ");
1230 utf_cat(msg, m->name);
1231 strcat(msg, " signature: ");
1232 utf_cat(msg, m->descriptor);
1236 va_start(ap, message);
1237 vsprintf(msg + strlen(msg), message, ap);
1240 u = utf_new_char(msg);
1244 MFREE(msg, char, msglen);
1246 /* throw exception */
1248 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1252 /* exceptions_throw_verifyerror_for_stack **************************************
1254 throws a java.lang.VerifyError for an invalid stack slot type
1257 m............method in which the error was found
1258 type.........the expected type
1261 an exception pointer (in any case -- either it is the newly created
1262 exception, or an exception thrown while trying to create it).
1264 *******************************************************************************/
1266 void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
1273 /* calculate exception message length */
1278 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1279 strlen(", method: ") + utf_bytes(m->name) +
1280 strlen(" signature: ") + utf_bytes(m->descriptor) +
1281 strlen(") Expecting to find longest-------typename on stack")
1284 /* allocate memory */
1286 msg = MNEW(char, msglen);
1288 /* generate message */
1291 strcpy(msg, "(class: ");
1292 utf_cat_classname(msg, m->class->name);
1293 strcat(msg, ", method: ");
1294 utf_cat(msg, m->name);
1295 strcat(msg, " signature: ");
1296 utf_cat(msg, m->descriptor);
1303 strcat(msg, "Expecting to find ");
1306 case TYPE_INT: typename = "integer"; break;
1307 case TYPE_LNG: typename = "long"; break;
1308 case TYPE_FLT: typename = "float"; break;
1309 case TYPE_DBL: typename = "double"; break;
1310 case TYPE_ADR: typename = "object/array"; break;
1311 case TYPE_RET: typename = "returnAddress"; break;
1312 default: typename = "<INVALID>"; assert(0); break;
1315 strcat(msg, typename);
1316 strcat(msg, " on stack");
1318 u = utf_new_char(msg);
1322 MFREE(msg, char, msglen);
1324 /* throw exception */
1326 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1330 /* exceptions_new_arithmeticexception ******************************************
1332 Generates a java.lang.ArithmeticException for the JIT compiler.
1334 *******************************************************************************/
1336 java_handle_t *exceptions_new_arithmeticexception(void)
1340 o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
1341 utf_division_by_zero);
1347 /* exceptions_new_arrayindexoutofboundsexception *******************************
1349 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1352 *******************************************************************************/
1354 java_handle_t *exceptions_new_arrayindexoutofboundsexception(s4 index)
1360 /* convert the index into a String, like Sun does */
1362 m = class_resolveclassmethod(class_java_lang_String,
1363 utf_new_char("valueOf"),
1364 utf_new_char("(I)Ljava/lang/String;"),
1365 class_java_lang_Object,
1369 return exceptions_get_exception();
1371 s = vm_call_method(m, NULL, index);
1374 return exceptions_get_exception();
1376 o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1380 return exceptions_get_exception();
1386 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1388 Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1391 *******************************************************************************/
1393 void exceptions_throw_arrayindexoutofboundsexception(void)
1395 exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1399 /* exceptions_throw_arraystoreexception ****************************************
1401 Generates and throws a java.lang.ArrayStoreException for the VM.
1403 *******************************************************************************/
1405 void exceptions_throw_arraystoreexception(void)
1407 exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1411 /* exceptions_new_classcastexception *******************************************
1413 Generates a java.lang.ClassCastException for the JIT compiler.
1415 *******************************************************************************/
1417 java_handle_t *exceptions_new_classcastexception(java_handle_t *o)
1423 LLNI_class_get(o, c);
1425 classname = c->name;
1427 e = exceptions_new_utf_utf(utf_java_lang_ClassCastException, classname);
1433 /* exceptions_throw_clonenotsupportedexception *********************************
1435 Generates and throws a java.lang.CloneNotSupportedException for the
1438 *******************************************************************************/
1440 void exceptions_throw_clonenotsupportedexception(void)
1442 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1446 /* exceptions_throw_illegalaccessexception *************************************
1448 Generates and throws a java.lang.IllegalAccessException for the VM.
1450 *******************************************************************************/
1452 void exceptions_throw_illegalaccessexception(utf *message)
1454 exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
1458 /* exceptions_throw_illegalargumentexception ***********************************
1460 Generates and throws a java.lang.IllegalArgumentException for the
1463 *******************************************************************************/
1465 void exceptions_throw_illegalargumentexception(void)
1467 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1471 /* exceptions_throw_illegalmonitorstateexception *******************************
1473 Generates and throws a java.lang.IllegalMonitorStateException for
1476 *******************************************************************************/
1478 void exceptions_throw_illegalmonitorstateexception(void)
1480 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1484 /* exceptions_throw_instantiationexception *************************************
1486 Generates and throws a java.lang.InstantiationException for the VM.
1488 *******************************************************************************/
1490 void exceptions_throw_instantiationexception(classinfo *c)
1492 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1496 /* exceptions_throw_interruptedexception ***************************************
1498 Generates and throws a java.lang.InterruptedException for the VM.
1500 *******************************************************************************/
1502 void exceptions_throw_interruptedexception(void)
1504 exceptions_throw_utf(utf_java_lang_InterruptedException);
1508 /* exceptions_throw_invocationtargetexception **********************************
1510 Generates and throws a java.lang.reflect.InvocationTargetException
1514 cause......cause exception object
1516 *******************************************************************************/
1518 void exceptions_throw_invocationtargetexception(java_handle_t *cause)
1520 exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1525 /* exceptions_throw_negativearraysizeexception *********************************
1527 Generates and throws a java.lang.NegativeArraySizeException for the
1530 *******************************************************************************/
1532 void exceptions_throw_negativearraysizeexception(void)
1534 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1538 /* exceptions_new_nullpointerexception *****************************************
1540 Generates a java.lang.NullPointerException for the VM system.
1542 *******************************************************************************/
1544 java_handle_t *exceptions_new_nullpointerexception(void)
1548 o = exceptions_new_utf(utf_java_lang_NullPointerException);
1554 /* exceptions_throw_nullpointerexception ***************************************
1556 Generates a java.lang.NullPointerException for the VM system and
1557 throw it in the VM system.
1559 *******************************************************************************/
1561 void exceptions_throw_nullpointerexception(void)
1563 exceptions_throw_utf(utf_java_lang_NullPointerException);
1567 /* exceptions_throw_privilegedactionexception **********************************
1569 Generates and throws a java.security.PrivilegedActionException.
1571 *******************************************************************************/
1573 void exceptions_throw_privilegedactionexception(java_handle_t *exception)
1575 exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
1580 /* exceptions_throw_stringindexoutofboundsexception ****************************
1582 Generates and throws a java.lang.StringIndexOutOfBoundsException
1585 *******************************************************************************/
1587 void exceptions_throw_stringindexoutofboundsexception(void)
1589 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1593 /* exceptions_classnotfoundexception_to_noclassdeffounderror *******************
1595 Check the exception for a ClassNotFoundException. If it is one,
1596 convert it to a NoClassDefFoundError.
1598 *******************************************************************************/
1600 void exceptions_classnotfoundexception_to_noclassdeffounderror(void)
1604 java_handle_t *cause;
1605 java_lang_Throwable *object;
1606 java_lang_String *s;
1608 /* Load java/lang/ClassNotFoundException for the instanceof
1611 c = load_class_bootstrap(utf_java_lang_ClassNotFoundException);
1616 /* Get the cause. */
1618 cause = exceptions_get_exception();
1620 /* Convert ClassNotFoundException's to NoClassDefFoundError's. */
1622 if (builtin_instanceof(cause, c)) {
1623 /* clear exception, because we are calling jit code again */
1625 exceptions_clear_exception();
1627 /* create new error */
1629 object = (java_lang_Throwable *) cause;
1630 LLNI_field_get_ref(object, detailMessage, s);
1632 o = exceptions_new_utf_javastring(utf_java_lang_NoClassDefFoundError,
1633 (java_handle_t *) s);
1635 /* we had an exception while creating the error */
1637 if (exceptions_get_exception())
1640 /* set new exception */
1642 exceptions_set_exception(o);
1647 /* exceptions_fillinstacktrace *************************************************
1649 Calls the fillInStackTrace-method of the currently thrown
1652 *******************************************************************************/
1654 java_handle_t *exceptions_fillinstacktrace(void)
1662 o = exceptions_get_and_clear_exception();
1666 /* resolve methodinfo pointer from exception object */
1668 LLNI_class_get(o, c);
1670 #if defined(ENABLE_JAVASE)
1671 m = class_resolvemethod(c,
1672 utf_fillInStackTrace,
1673 utf_void__java_lang_Throwable);
1674 #elif defined(ENABLE_JAVAME_CLDC1_1)
1675 m = class_resolvemethod(c,
1676 utf_fillInStackTrace,
1679 #error IMPLEMENT ME!
1684 (void) vm_call_method(m, o);
1686 /* return exception object */
1692 /* exceptions_handle_exception *************************************************
1694 Try to find an exception handler for the given exception and return it.
1695 If no handler is found, exit the monitor of the method (if any)
1699 xptr.........the exception object
1700 xpc..........PC of where the exception was thrown
1701 pv...........Procedure Value of the current method
1702 sp...........current stack pointer
1705 the address of the first matching exception handler, or
1706 NULL if no handler was found
1708 *******************************************************************************/
1710 #if defined(ENABLE_JIT)
1711 void *exceptions_handle_exception(java_object_t *xptro, void *xpc, void *pv, void *sp)
1713 stackframeinfo_t sfi;
1714 java_handle_t *xptr;
1717 exceptiontable_t *et;
1718 exceptiontable_entry_t *ete;
1720 classref_or_classinfo cr;
1722 #if defined(ENABLE_THREADS)
1728 /* Addresses are 31 bit integers */
1729 # define ADDR_MASK(x) (void *) ((uintptr_t) (x) & 0x7FFFFFFF)
1731 # define ADDR_MASK(x) (x)
1734 xptr = LLNI_WRAP(xptro);
1735 xpc = ADDR_MASK(xpc);
1737 /* Fill and add a stackframeinfo (XPC is equal to RA). */
1739 stacktrace_stackframeinfo_add(&sfi, pv, sp, xpc, xpc);
1743 /* Get the codeinfo for the current method. */
1745 code = code_get_codeinfo_for_pv(pv);
1747 /* Get the methodinfo pointer from the codeinfo pointer. For
1748 asm_vm_call_method the codeinfo pointer is NULL and we simply
1749 can return the proper exception handler. */
1752 result = (void *) (uintptr_t) &asm_vm_call_method_exception_handler;
1753 goto exceptions_handle_exception_return;
1758 #if !defined(NDEBUG)
1759 /* print exception trace */
1761 if (opt_TraceExceptions)
1762 trace_exception(LLNI_DIRECT(xptr), m, xpc);
1764 # if defined(ENABLE_VMLOG)
1765 vmlog_cacao_throw(xptr);
1769 /* Get the exception table. */
1771 et = code->exceptiontable;
1774 /* Iterate over all exception table entries. */
1778 for (i = 0; i < et->length; i++, ete++) {
1779 /* is the xpc is the current catch range */
1781 if ((ADDR_MASK(ete->startpc) <= xpc) && (xpc < ADDR_MASK(ete->endpc))) {
1782 cr = ete->catchtype;
1784 /* NULL catches everything */
1786 if (cr.any == NULL) {
1787 #if !defined(NDEBUG)
1788 /* Print stacktrace of exception when caught. */
1790 # if defined(ENABLE_VMLOG)
1791 vmlog_cacao_catch(xptr);
1794 if (opt_TraceExceptions) {
1795 exceptions_print_exception(xptr);
1796 stacktrace_print_trace(xptr);
1800 result = ete->handlerpc;
1801 goto exceptions_handle_exception_return;
1804 /* resolve or load/link the exception class */
1806 if (IS_CLASSREF(cr)) {
1807 /* The exception class reference is unresolved. */
1808 /* We have to do _eager_ resolving here. While the
1809 class of the exception object is guaranteed to be
1810 loaded, it may well have been loaded by a different
1811 loader than the defining loader of m's class, which
1812 is the one we must use to resolve the catch
1813 class. Thus lazy resolving might fail, even if the
1814 result of the resolution would be an already loaded
1817 c = resolve_classref_eager(cr.ref);
1820 /* Exception resolving the exception class, argh! */
1821 goto exceptions_handle_exception_return;
1824 /* Ok, we resolved it. Enter it in the table, so we
1825 don't have to do this again. */
1826 /* XXX this write should be atomic. Is it? */
1828 ete->catchtype.cls = c;
1833 /* XXX I don't think this case can ever happen. -Edwin */
1834 if (!(c->state & CLASS_LOADED))
1835 /* use the methods' classloader */
1836 if (!load_class_from_classloader(c->name,
1837 m->class->classloader))
1838 goto exceptions_handle_exception_return;
1840 /* XXX I think, if it is not linked, we can be sure
1841 that the exception object is no (indirect) instance
1842 of it, no? -Edwin */
1843 if (!(c->state & CLASS_LINKED))
1845 goto exceptions_handle_exception_return;
1848 /* is the thrown exception an instance of the catch class? */
1850 if (builtin_instanceof(xptr, c)) {
1851 #if !defined(NDEBUG)
1852 /* Print stacktrace of exception when caught. */
1854 # if defined(ENABLE_VMLOG)
1855 vmlog_cacao_catch(xptr);
1858 if (opt_TraceExceptions) {
1859 exceptions_print_exception(xptr);
1860 stacktrace_print_trace(xptr);
1864 result = ete->handlerpc;
1865 goto exceptions_handle_exception_return;
1871 #if defined(ENABLE_THREADS)
1872 /* Is this method realization synchronized? */
1874 if (code_is_synchronized(code)) {
1875 /* Get synchronization object. */
1877 o = *((java_object_t **) (((uintptr_t) sp) + code->synchronizedoffset));
1881 lock_monitor_exit(LLNI_QUICKWRAP(o));
1885 /* none of the exceptions catch this one */
1887 #if !defined(NDEBUG)
1888 # if defined(ENABLE_VMLOG)
1889 vmlog_cacao_unwnd_method(m);
1892 # if defined(ENABLE_DEBUG_FILTER)
1893 if (show_filters_test_verbosecall_exit(m)) {
1896 /* outdent the log message */
1898 if (opt_verbosecall) {
1899 if (TRACEJAVACALLINDENT)
1900 TRACEJAVACALLINDENT--;
1902 log_text("exceptions_handle_exception: WARNING: unmatched unindent");
1905 # if defined(ENABLE_DEBUG_FILTER)
1908 #endif /* !defined(NDEBUG) */
1912 exceptions_handle_exception_return:
1914 /* Remove the stackframeinfo. */
1916 stacktrace_stackframeinfo_remove(&sfi);
1920 #endif /* defined(ENABLE_JIT) */
1923 /* exceptions_print_exception **************************************************
1925 Prints an exception, the detail message and the cause, if
1926 available, with CACAO internal functions to stdout.
1928 *******************************************************************************/
1930 void exceptions_print_exception(java_handle_t *xptr)
1932 java_lang_Throwable *t;
1933 #if defined(ENABLE_JAVASE)
1934 java_lang_Throwable *cause;
1936 java_lang_String *s;
1940 t = (java_lang_Throwable *) xptr;
1947 #if defined(ENABLE_JAVASE)
1948 LLNI_field_get_ref(t, cause, cause);
1951 /* print the root exception */
1953 LLNI_class_get(t, c);
1954 utf_display_printable_ascii_classname(c->name);
1956 LLNI_field_get_ref(t, detailMessage, s);
1959 u = javastring_toutf((java_handle_t *) s, false);
1962 utf_display_printable_ascii(u);
1967 #if defined(ENABLE_JAVASE)
1968 /* print the cause if available */
1970 if ((cause != NULL) && (cause != t)) {
1971 printf("Caused by: ");
1973 LLNI_class_get(cause, c);
1974 utf_display_printable_ascii_classname(c->name);
1976 LLNI_field_get_ref(cause, detailMessage, s);
1979 u = javastring_toutf((java_handle_t *) s, false);
1982 utf_display_printable_ascii(u);
1991 /* exceptions_print_current_exception ******************************************
1993 Prints the current pending exception, the detail message and the
1994 cause, if available, with CACAO internal functions to stdout.
1996 *******************************************************************************/
1998 void exceptions_print_current_exception(void)
2002 o = exceptions_get_exception();
2004 exceptions_print_exception(o);
2008 /* exceptions_print_stacktrace *************************************************
2010 Prints a pending exception with Throwable.printStackTrace(). If
2011 there happens an exception during printStackTrace(), we print the
2012 thrown exception and the original one.
2014 NOTE: This function calls Java code.
2016 *******************************************************************************/
2018 void exceptions_print_stacktrace(void)
2020 java_handle_t *oxptr;
2021 java_handle_t *xptr;
2025 /* get original exception */
2027 oxptr = exceptions_get_and_clear_exception();
2030 vm_abort("exceptions_print_stacktrace: no exception thrown");
2032 /* clear exception, because we are calling jit code again */
2034 LLNI_class_get(oxptr, c);
2036 /* find the printStackTrace() method */
2038 m = class_resolveclassmethod(c,
2039 utf_printStackTrace,
2041 class_java_lang_Object,
2045 vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
2047 /* print compatibility message */
2049 fprintf(stderr, "Exception in thread \"main\" ");
2051 /* print the stacktrace */
2053 (void) vm_call_method(m, oxptr);
2055 /* This normally means, we are EXTREMLY out of memory or
2056 have a serious problem while printStackTrace. But may
2057 be another exception, so print it. */
2059 xptr = exceptions_get_exception();
2062 fprintf(stderr, "Exception while printStackTrace(): ");
2064 /* now print original exception */
2066 exceptions_print_exception(xptr);
2067 stacktrace_print_trace(xptr);
2069 /* now print original exception */
2071 fprintf(stderr, "Original exception was: ");
2072 exceptions_print_exception(oxptr);
2073 stacktrace_print_trace(oxptr);
2081 * These are local overrides for various environment variables in Emacs.
2082 * Please do not remove this and leave it at the end of the file, where
2083 * Emacs will automagically detect them.
2084 * ---------------------------------------------------------------------
2087 * indent-tabs-mode: t
2091 * vim:noexpandtab:sw=4:ts=4: