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"
74 #if defined(ENABLE_VMLOG)
75 #include <vmlog_cacao.h>
79 /* for raising exceptions from native methods *********************************/
81 #if !defined(ENABLE_THREADS)
82 java_object_t *_no_threads_exceptionptr = NULL;
86 /* exceptions_init *************************************************************
88 Initialize the exceptions subsystem.
90 *******************************************************************************/
92 void exceptions_init(void)
94 #if !(defined(__ARM__) && defined(__LINUX__))
95 /* On arm-linux the first memory page can't be mmap'ed, as it
96 contains the exception vectors. */
100 /* mmap a memory page at address 0x0, so our hardware-exceptions
103 pagesize = getpagesize();
105 (void) memory_mmap_anon(NULL, pagesize, PROT_NONE, MAP_PRIVATE | MAP_FIXED);
108 /* check if we get into trouble with our hardware-exceptions */
110 if (OFFSET(java_bytearray_t, data) <= EXCEPTION_HARDWARE_LARGEST)
111 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);
115 /* exceptions_get_exception ****************************************************
117 Returns the current exception pointer of the current thread.
119 *******************************************************************************/
121 java_handle_t *exceptions_get_exception(void)
125 #if defined(ENABLE_THREADS)
131 /* Get the exception. */
135 #if defined(ENABLE_THREADS)
136 o = t->_exceptionptr;
138 o = _no_threads_exceptionptr;
145 /* Return the exception. */
151 /* exceptions_set_exception ****************************************************
153 Sets the exception pointer of the current thread.
155 *******************************************************************************/
157 void exceptions_set_exception(java_handle_t *e)
162 #if defined(ENABLE_THREADS)
168 /* Set the exception. */
175 if (opt_DebugExceptions) {
176 printf("[exceptions_set_exception : t=%p, o=%p, class=",
177 (void *) t, (void *) o);
178 class_print(o->vftbl->class);
183 #if defined(ENABLE_THREADS)
184 t->_exceptionptr = o;
186 _no_threads_exceptionptr = o;
193 /* exceptions_clear_exception **************************************************
195 Clears the current exception pointer of the current thread.
197 *******************************************************************************/
199 void exceptions_clear_exception(void)
203 #if defined(ENABLE_THREADS)
209 /* Set the exception. */
212 if (opt_DebugExceptions) {
213 printf("[exceptions_clear_exception: t=%p]\n", (void *) t);
217 #if defined(ENABLE_THREADS)
218 t->_exceptionptr = NULL;
220 _no_threads_exceptionptr = NULL;
225 /* exceptions_get_and_clear_exception ******************************************
227 Gets the exception pointer of the current thread and clears it.
228 This function may return NULL.
230 *******************************************************************************/
232 java_handle_t *exceptions_get_and_clear_exception(void)
236 /* Get the exception... */
238 o = exceptions_get_exception();
240 /* ...and clear the exception if it is set. */
243 exceptions_clear_exception();
245 /* return the exception */
251 /* exceptions_abort ************************************************************
253 Prints exception to be thrown and aborts.
256 classname....class name
257 message......exception message
259 *******************************************************************************/
261 static void exceptions_abort(utf *classname, utf *message)
263 log_println("exception thrown while VM is initializing: ");
266 utf_display_printable_ascii_classname(classname);
268 if (message != NULL) {
270 utf_display_printable_ascii_classname(message);
275 vm_abort("Aborting...");
279 /* exceptions_new_utf **********************************************************
281 Creates an exception object with the given name and initalizes it.
284 classname....class name in UTF-8
286 *******************************************************************************/
288 static java_handle_t *exceptions_new_utf(utf *classname)
294 exceptions_abort(classname, NULL);
296 c = load_class_bootstrap(classname);
299 return exceptions_get_exception();
301 o = native_new_and_init(c);
304 return exceptions_get_exception();
310 /* exceptions_throw_utf ********************************************************
312 Creates an exception object with the given name, initalizes and
316 classname....class name in UTF-8
318 *******************************************************************************/
320 static void exceptions_throw_utf(utf *classname)
324 o = exceptions_new_utf(classname);
329 exceptions_set_exception(o);
333 /* exceptions_throw_utf_throwable **********************************************
335 Creates an exception object with the given name and initalizes it
336 with the given java/lang/Throwable exception.
339 classname....class name in UTF-8
340 cause........the given Throwable
342 *******************************************************************************/
344 static void exceptions_throw_utf_throwable(utf *classname,
345 java_handle_t *cause)
350 java_lang_Throwable *object;
353 exceptions_abort(classname, NULL);
355 object = (java_lang_Throwable *) cause;
357 c = load_class_bootstrap(classname);
369 /* call initializer */
371 m = class_resolveclassmethod(c,
373 utf_java_lang_Throwable__void,
380 (void) vm_call_method(m, o, cause);
382 exceptions_set_exception(o);
386 /* exceptions_throw_utf_exception **********************************************
388 Creates an exception object with the given name and initalizes it
389 with the given java/lang/Exception exception.
392 classname....class name in UTF-8
393 exception....the given Exception
395 *******************************************************************************/
397 static void exceptions_throw_utf_exception(utf *classname,
398 java_handle_t *exception)
405 exceptions_abort(classname, NULL);
407 c = load_class_bootstrap(classname);
419 /* call initializer */
421 m = class_resolveclassmethod(c,
423 utf_java_lang_Exception__V,
430 (void) vm_call_method(m, o, exception);
432 exceptions_set_exception(o);
436 /* exceptions_throw_utf_cause **************************************************
438 Creates an exception object with the given name and initalizes it
439 with the given java/lang/Throwable exception with initCause.
442 classname....class name in UTF-8
443 cause........the given Throwable
445 *******************************************************************************/
447 static void exceptions_throw_utf_cause(utf *classname, java_handle_t *cause)
453 java_lang_Throwable *object;
456 exceptions_abort(classname, NULL);
458 object = (java_lang_Throwable *) cause;
460 c = load_class_bootstrap(classname);
472 /* call initializer */
474 m = class_resolveclassmethod(c,
476 utf_java_lang_String__void,
483 LLNI_field_get_ref(object, detailMessage, s);
485 (void) vm_call_method(m, o, s);
489 m = class_resolveclassmethod(c,
491 utf_java_lang_Throwable__java_lang_Throwable,
498 (void) vm_call_method(m, o, cause);
500 exceptions_set_exception(o);
504 /* exceptions_new_utf_javastring ***********************************************
506 Creates an exception object with the given name and initalizes it
507 with the given java/lang/String message.
510 classname....class name in UTF-8
511 message......the message as a java.lang.String
514 an exception pointer (in any case -- either it is the newly created
515 exception, or an exception thrown while trying to create it).
517 *******************************************************************************/
519 static java_handle_t *exceptions_new_utf_javastring(utf *classname,
520 java_handle_t *message)
526 exceptions_abort(classname, NULL);
528 c = load_class_bootstrap(classname);
531 return exceptions_get_exception();
533 o = native_new_and_init_string(c, message);
536 return exceptions_get_exception();
542 /* exceptions_new_utf_utf ******************************************************
544 Creates an exception object with the given name and initalizes it
545 with the given utf message.
548 classname....class name in UTF-8
549 message......the message as an utf *
552 an exception pointer (in any case -- either it is the newly created
553 exception, or an exception thrown while trying to create it).
555 *******************************************************************************/
557 static java_handle_t *exceptions_new_utf_utf(utf *classname, utf *message)
564 exceptions_abort(classname, message);
566 c = load_class_bootstrap(classname);
569 return exceptions_get_exception();
571 s = javastring_new(message);
574 return exceptions_get_exception();
576 o = native_new_and_init_string(c, s);
579 return exceptions_get_exception();
585 /* exceptions_throw_utf_utf ****************************************************
587 Creates an exception object with the given name, initalizes and
588 throws it with the given utf message.
591 classname....class name in UTF-8
592 message......the message as an utf *
594 *******************************************************************************/
596 static void exceptions_throw_utf_utf(utf *classname, utf *message)
600 o = exceptions_new_utf_utf(classname, message);
602 exceptions_set_exception(o);
606 /* exceptions_new_abstractmethoderror ****************************************
608 Generates a java.lang.AbstractMethodError for the VM.
610 *******************************************************************************/
612 java_handle_t *exceptions_new_abstractmethoderror(void)
616 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
622 /* exceptions_new_error ********************************************************
624 Generates a java.lang.Error for the VM.
626 *******************************************************************************/
628 #if defined(ENABLE_JAVAME_CLDC1_1)
629 static java_handle_t *exceptions_new_error(utf *message)
633 o = exceptions_new_utf_utf(utf_java_lang_Error, message);
640 /* exceptions_asm_new_abstractmethoderror **************************************
642 Generates a java.lang.AbstractMethodError for
643 asm_abstractmethoderror.
645 *******************************************************************************/
647 java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
649 stackframeinfo_t sfi;
653 /* Fill and add a stackframeinfo (XPC is equal to RA). */
655 stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra);
657 /* create the exception */
659 #if defined(ENABLE_JAVASE)
660 e = exceptions_new_abstractmethoderror();
662 e = exceptions_new_error(utf_java_lang_AbstractMethodError);
665 /* Remove the stackframeinfo. */
667 stacktrace_stackframeinfo_remove(&sfi);
669 /* unwrap the exception */
670 /* ATTENTION: do the this _after_ the stackframeinfo was removed */
678 /* exceptions_new_arraystoreexception ******************************************
680 Generates a java.lang.ArrayStoreException for the VM.
682 *******************************************************************************/
684 java_handle_t *exceptions_new_arraystoreexception(void)
688 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
694 /* exceptions_throw_abstractmethoderror ****************************************
696 Generates and throws a java.lang.AbstractMethodError for the VM.
698 *******************************************************************************/
700 void exceptions_throw_abstractmethoderror(void)
702 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
706 /* exceptions_throw_classcircularityerror **************************************
708 Generates and throws a java.lang.ClassCircularityError for the
712 c....the class in which the error was found
714 *******************************************************************************/
716 void exceptions_throw_classcircularityerror(classinfo *c)
718 exceptions_throw_utf_utf(utf_java_lang_ClassCircularityError, c->name);
722 /* exceptions_throw_classformaterror *******************************************
724 Generates and throws a java.lang.ClassFormatError for the VM.
727 c............the class in which the error was found
728 message......UTF-8 format string
730 *******************************************************************************/
732 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
739 /* calculate message length */
744 msglen += utf_bytes(c->name) + strlen(" (");
746 va_start(ap, message);
747 msglen += get_variable_message_length(message, ap);
751 msglen += strlen(")");
753 msglen += strlen("0");
755 /* allocate a buffer */
757 msg = MNEW(char, msglen);
759 /* print message into allocated buffer */
762 utf_copy_classname(msg, c->name);
766 va_start(ap, message);
767 vsprintf(msg + strlen(msg), message, ap);
773 u = utf_new_char(msg);
777 MFREE(msg, char, msglen);
779 /* throw exception */
781 exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
785 /* exceptions_throw_classnotfoundexception *************************************
787 Generates and throws a java.lang.ClassNotFoundException for the
791 name.........name of the class not found as a utf *
793 *******************************************************************************/
795 void exceptions_throw_classnotfoundexception(utf *name)
797 exceptions_throw_utf_utf(utf_java_lang_ClassNotFoundException, name);
801 /* exceptions_throw_noclassdeffounderror ***************************************
803 Generates and throws a java.lang.NoClassDefFoundError.
806 name.........name of the class not found as a utf *
808 *******************************************************************************/
810 void exceptions_throw_noclassdeffounderror(utf *name)
812 exceptions_throw_utf_utf(utf_java_lang_NoClassDefFoundError, name);
816 /* exceptions_throw_noclassdeffounderror_cause *********************************
818 Generates and throws a java.lang.NoClassDefFoundError with the
821 *******************************************************************************/
823 void exceptions_throw_noclassdeffounderror_cause(java_handle_t *cause)
825 exceptions_throw_utf_cause(utf_java_lang_NoClassDefFoundError, cause);
829 /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
831 Generates and throws a java.lang.NoClassDefFoundError with a
835 name.........name of the class not found as a utf *
837 *******************************************************************************/
839 void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
845 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
846 utf_bytes(name) + strlen(")") + strlen("0");
848 msg = MNEW(char, msglen);
850 utf_copy_classname(msg, c->name);
851 strcat(msg, " (wrong name: ");
852 utf_cat_classname(msg, name);
855 u = utf_new_char(msg);
857 MFREE(msg, char, msglen);
859 exceptions_throw_noclassdeffounderror(u);
863 /* exceptions_throw_exceptionininitializererror ********************************
865 Generates and throws a java.lang.ExceptionInInitializerError for
869 cause......cause exception object
871 *******************************************************************************/
873 void exceptions_throw_exceptionininitializererror(java_handle_t *cause)
875 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
880 /* exceptions_throw_incompatibleclasschangeerror *******************************
882 Generates and throws a java.lang.IncompatibleClassChangeError for
886 message......UTF-8 message format string
888 *******************************************************************************/
890 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
896 /* calculate exception message length */
898 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
900 /* allocate memory */
902 msg = MNEW(char, msglen);
904 utf_copy_classname(msg, c->name);
905 strcat(msg, message);
907 u = utf_new_char(msg);
911 MFREE(msg, char, msglen);
913 /* throw exception */
915 exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
919 /* exceptions_throw_instantiationerror *****************************************
921 Generates and throws a java.lang.InstantiationError for the VM.
923 *******************************************************************************/
925 void exceptions_throw_instantiationerror(classinfo *c)
927 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
931 /* exceptions_throw_internalerror **********************************************
933 Generates and throws a java.lang.InternalError for the VM.
936 message......UTF-8 message format string
938 *******************************************************************************/
940 void exceptions_throw_internalerror(const char *message, ...)
947 /* calculate exception message length */
949 va_start(ap, message);
950 msglen = get_variable_message_length(message, ap);
953 /* allocate memory */
955 msg = MNEW(char, msglen);
957 /* generate message */
959 va_start(ap, message);
960 vsprintf(msg, message, ap);
963 u = utf_new_char(msg);
967 MFREE(msg, char, msglen);
969 /* throw exception */
971 exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
975 /* exceptions_throw_linkageerror ***********************************************
977 Generates and throws java.lang.LinkageError with an error message.
980 message......UTF-8 message
981 c............class related to the error. If this is != NULL
982 the name of c is appended to the error message.
984 *******************************************************************************/
986 void exceptions_throw_linkageerror(const char *message, classinfo *c)
992 /* calculate exception message length */
994 len = strlen(message) + 1;
997 len += utf_bytes(c->name);
999 /* allocate memory */
1001 msg = MNEW(char, len);
1003 /* generate message */
1005 strcpy(msg, message);
1008 utf_cat_classname(msg, c->name);
1010 u = utf_new_char(msg);
1014 MFREE(msg, char, len);
1016 exceptions_throw_utf_utf(utf_java_lang_LinkageError, u);
1020 /* exceptions_throw_nosuchfielderror *******************************************
1022 Generates and throws a java.lang.NoSuchFieldError with an error
1026 c............class in which the field was not found
1027 name.........name of the field
1029 *******************************************************************************/
1031 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
1037 /* calculate exception message length */
1039 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
1041 /* allocate memory */
1043 msg = MNEW(char, msglen);
1045 /* generate message */
1047 utf_copy_classname(msg, c->name);
1051 u = utf_new_char(msg);
1055 MFREE(msg, char, msglen);
1057 exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
1061 /* exceptions_throw_nosuchmethoderror ******************************************
1063 Generates and throws a java.lang.NoSuchMethodError with an error
1067 c............class in which the method was not found
1068 name.........name of the method
1069 desc.........descriptor of the method
1071 *******************************************************************************/
1073 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
1079 /* calculate exception message length */
1081 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
1082 utf_bytes(desc) + strlen("0");
1084 /* allocate memory */
1086 msg = MNEW(char, msglen);
1088 /* generate message */
1090 utf_copy_classname(msg, c->name);
1095 u = utf_new_char(msg);
1099 MFREE(msg, char, msglen);
1101 #if defined(ENABLE_JAVASE)
1102 exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
1104 exceptions_throw_utf_utf(utf_java_lang_Error, u);
1109 /* exceptions_throw_outofmemoryerror *******************************************
1111 Generates and throws an java.lang.OutOfMemoryError for the VM.
1113 *******************************************************************************/
1115 void exceptions_throw_outofmemoryerror(void)
1117 exceptions_throw_utf(utf_java_lang_OutOfMemoryError);
1121 /* exceptions_throw_unsatisfiedlinkerror ***************************************
1123 Generates and throws a java.lang.UnsatisfiedLinkError for the
1127 name......UTF-8 name string
1129 *******************************************************************************/
1131 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1133 #if defined(ENABLE_JAVASE)
1134 exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1136 exceptions_throw_utf_utf(utf_java_lang_Error, name);
1141 /* exceptions_throw_unsupportedclassversionerror *******************************
1143 Generates and throws a java.lang.UnsupportedClassVersionError for
1147 c............class in which the method was not found
1148 message......UTF-8 format string
1150 *******************************************************************************/
1152 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1158 /* calculate exception message length */
1161 utf_bytes(c->name) +
1162 strlen(" (Unsupported major.minor version 00.0)") +
1165 /* allocate memory */
1167 msg = MNEW(char, msglen);
1169 /* generate message */
1171 utf_copy_classname(msg, c->name);
1172 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1175 u = utf_new_char(msg);
1179 MFREE(msg, char, msglen);
1181 /* throw exception */
1183 exceptions_throw_utf_utf(utf_java_lang_UnsupportedClassVersionError, u);
1187 /* exceptions_throw_verifyerror ************************************************
1189 Generates and throws a java.lang.VerifyError for the JIT compiler.
1192 m............method in which the error was found
1193 message......UTF-8 format string
1195 *******************************************************************************/
1197 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1204 /* calculate exception message length */
1210 strlen("(class: ") + utf_bytes(m->class->name) +
1211 strlen(", method: ") + utf_bytes(m->name) +
1212 strlen(" signature: ") + utf_bytes(m->descriptor) +
1213 strlen(") ") + strlen("0");
1215 va_start(ap, message);
1216 msglen += get_variable_message_length(message, ap);
1219 /* allocate memory */
1221 msg = MNEW(char, msglen);
1223 /* generate message */
1226 strcpy(msg, "(class: ");
1227 utf_cat_classname(msg, m->class->name);
1228 strcat(msg, ", method: ");
1229 utf_cat(msg, m->name);
1230 strcat(msg, " signature: ");
1231 utf_cat(msg, m->descriptor);
1235 va_start(ap, message);
1236 vsprintf(msg + strlen(msg), message, ap);
1239 u = utf_new_char(msg);
1243 MFREE(msg, char, msglen);
1245 /* throw exception */
1247 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1251 /* exceptions_throw_verifyerror_for_stack **************************************
1253 throws a java.lang.VerifyError for an invalid stack slot type
1256 m............method in which the error was found
1257 type.........the expected type
1260 an exception pointer (in any case -- either it is the newly created
1261 exception, or an exception thrown while trying to create it).
1263 *******************************************************************************/
1265 void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
1272 /* calculate exception message length */
1277 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1278 strlen(", method: ") + utf_bytes(m->name) +
1279 strlen(" signature: ") + utf_bytes(m->descriptor) +
1280 strlen(") Expecting to find longest-------typename on stack")
1283 /* allocate memory */
1285 msg = MNEW(char, msglen);
1287 /* generate message */
1290 strcpy(msg, "(class: ");
1291 utf_cat_classname(msg, m->class->name);
1292 strcat(msg, ", method: ");
1293 utf_cat(msg, m->name);
1294 strcat(msg, " signature: ");
1295 utf_cat(msg, m->descriptor);
1302 strcat(msg, "Expecting to find ");
1305 case TYPE_INT: typename = "integer"; break;
1306 case TYPE_LNG: typename = "long"; break;
1307 case TYPE_FLT: typename = "float"; break;
1308 case TYPE_DBL: typename = "double"; break;
1309 case TYPE_ADR: typename = "object/array"; break;
1310 case TYPE_RET: typename = "returnAddress"; break;
1311 default: typename = "<INVALID>"; assert(0); break;
1314 strcat(msg, typename);
1315 strcat(msg, " on stack");
1317 u = utf_new_char(msg);
1321 MFREE(msg, char, msglen);
1323 /* throw exception */
1325 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1329 /* exceptions_new_arithmeticexception ******************************************
1331 Generates a java.lang.ArithmeticException for the JIT compiler.
1333 *******************************************************************************/
1335 java_handle_t *exceptions_new_arithmeticexception(void)
1339 o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
1340 utf_division_by_zero);
1346 /* exceptions_new_arrayindexoutofboundsexception *******************************
1348 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1351 *******************************************************************************/
1353 java_handle_t *exceptions_new_arrayindexoutofboundsexception(s4 index)
1359 /* convert the index into a String, like Sun does */
1361 m = class_resolveclassmethod(class_java_lang_String,
1362 utf_new_char("valueOf"),
1363 utf_new_char("(I)Ljava/lang/String;"),
1364 class_java_lang_Object,
1368 return exceptions_get_exception();
1370 s = vm_call_method(m, NULL, index);
1373 return exceptions_get_exception();
1375 o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1379 return exceptions_get_exception();
1385 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1387 Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1390 *******************************************************************************/
1392 void exceptions_throw_arrayindexoutofboundsexception(void)
1394 exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1398 /* exceptions_throw_arraystoreexception ****************************************
1400 Generates and throws a java.lang.ArrayStoreException for the VM.
1402 *******************************************************************************/
1404 void exceptions_throw_arraystoreexception(void)
1406 exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1410 /* exceptions_new_classcastexception *******************************************
1412 Generates a java.lang.ClassCastException for the JIT compiler.
1414 *******************************************************************************/
1416 java_handle_t *exceptions_new_classcastexception(java_handle_t *o)
1422 LLNI_class_get(o, c);
1424 classname = c->name;
1426 e = exceptions_new_utf_utf(utf_java_lang_ClassCastException, classname);
1432 /* exceptions_throw_clonenotsupportedexception *********************************
1434 Generates and throws a java.lang.CloneNotSupportedException for the
1437 *******************************************************************************/
1439 void exceptions_throw_clonenotsupportedexception(void)
1441 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1445 /* exceptions_throw_illegalaccessexception *************************************
1447 Generates and throws a java.lang.IllegalAccessException for the VM.
1449 *******************************************************************************/
1451 void exceptions_throw_illegalaccessexception(utf *message)
1453 exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
1457 /* exceptions_throw_illegalargumentexception ***********************************
1459 Generates and throws a java.lang.IllegalArgumentException for the
1462 *******************************************************************************/
1464 void exceptions_throw_illegalargumentexception(void)
1466 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1470 /* exceptions_throw_illegalmonitorstateexception *******************************
1472 Generates and throws a java.lang.IllegalMonitorStateException for
1475 *******************************************************************************/
1477 void exceptions_throw_illegalmonitorstateexception(void)
1479 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1483 /* exceptions_throw_instantiationexception *************************************
1485 Generates and throws a java.lang.InstantiationException for the VM.
1487 *******************************************************************************/
1489 void exceptions_throw_instantiationexception(classinfo *c)
1491 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1495 /* exceptions_throw_interruptedexception ***************************************
1497 Generates and throws a java.lang.InterruptedException for the VM.
1499 *******************************************************************************/
1501 void exceptions_throw_interruptedexception(void)
1503 exceptions_throw_utf(utf_java_lang_InterruptedException);
1507 /* exceptions_throw_invocationtargetexception **********************************
1509 Generates and throws a java.lang.reflect.InvocationTargetException
1513 cause......cause exception object
1515 *******************************************************************************/
1517 void exceptions_throw_invocationtargetexception(java_handle_t *cause)
1519 exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1524 /* exceptions_throw_negativearraysizeexception *********************************
1526 Generates and throws a java.lang.NegativeArraySizeException for the
1529 *******************************************************************************/
1531 void exceptions_throw_negativearraysizeexception(void)
1533 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1537 /* exceptions_new_nullpointerexception *****************************************
1539 Generates a java.lang.NullPointerException for the VM system.
1541 *******************************************************************************/
1543 java_handle_t *exceptions_new_nullpointerexception(void)
1547 o = exceptions_new_utf(utf_java_lang_NullPointerException);
1553 /* exceptions_throw_nullpointerexception ***************************************
1555 Generates a java.lang.NullPointerException for the VM system and
1556 throw it in the VM system.
1558 *******************************************************************************/
1560 void exceptions_throw_nullpointerexception(void)
1562 exceptions_throw_utf(utf_java_lang_NullPointerException);
1566 /* exceptions_throw_privilegedactionexception **********************************
1568 Generates and throws a java.security.PrivilegedActionException.
1570 *******************************************************************************/
1572 void exceptions_throw_privilegedactionexception(java_handle_t *exception)
1574 exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
1579 /* exceptions_throw_stringindexoutofboundsexception ****************************
1581 Generates and throws a java.lang.StringIndexOutOfBoundsException
1584 *******************************************************************************/
1586 void exceptions_throw_stringindexoutofboundsexception(void)
1588 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1592 /* exceptions_classnotfoundexception_to_noclassdeffounderror *******************
1594 Check the exception for a ClassNotFoundException. If it is one,
1595 convert it to a NoClassDefFoundError.
1597 *******************************************************************************/
1599 void exceptions_classnotfoundexception_to_noclassdeffounderror(void)
1603 java_handle_t *cause;
1604 java_lang_Throwable *object;
1605 java_lang_String *s;
1607 /* Load java/lang/ClassNotFoundException for the instanceof
1610 c = load_class_bootstrap(utf_java_lang_ClassNotFoundException);
1615 /* Get the cause. */
1617 cause = exceptions_get_exception();
1619 /* Convert ClassNotFoundException's to NoClassDefFoundError's. */
1621 if (builtin_instanceof(cause, c)) {
1622 /* clear exception, because we are calling jit code again */
1624 exceptions_clear_exception();
1626 /* create new error */
1628 object = (java_lang_Throwable *) cause;
1629 LLNI_field_get_ref(object, detailMessage, s);
1631 o = exceptions_new_utf_javastring(utf_java_lang_NoClassDefFoundError,
1632 (java_handle_t *) s);
1634 /* we had an exception while creating the error */
1636 if (exceptions_get_exception())
1639 /* set new exception */
1641 exceptions_set_exception(o);
1646 /* exceptions_fillinstacktrace *************************************************
1648 Calls the fillInStackTrace-method of the currently thrown
1651 *******************************************************************************/
1653 java_handle_t *exceptions_fillinstacktrace(void)
1661 o = exceptions_get_and_clear_exception();
1665 /* resolve methodinfo pointer from exception object */
1667 LLNI_class_get(o, c);
1669 #if defined(ENABLE_JAVASE)
1670 m = class_resolvemethod(c,
1671 utf_fillInStackTrace,
1672 utf_void__java_lang_Throwable);
1673 #elif defined(ENABLE_JAVAME_CLDC1_1)
1674 m = class_resolvemethod(c,
1675 utf_fillInStackTrace,
1678 #error IMPLEMENT ME!
1683 (void) vm_call_method(m, o);
1685 /* return exception object */
1691 /* exceptions_handle_exception *************************************************
1693 Try to find an exception handler for the given exception and return it.
1694 If no handler is found, exit the monitor of the method (if any)
1698 xptr.........the exception object
1699 xpc..........PC of where the exception was thrown
1700 pv...........Procedure Value of the current method
1701 sp...........current stack pointer
1704 the address of the first matching exception handler, or
1705 NULL if no handler was found
1707 *******************************************************************************/
1709 #if defined(ENABLE_JIT)
1710 void *exceptions_handle_exception(java_object_t *xptro, void *xpc, void *pv, void *sp)
1712 stackframeinfo_t sfi;
1713 java_handle_t *xptr;
1716 exceptiontable_t *et;
1717 exceptiontable_entry_t *ete;
1719 classref_or_classinfo cr;
1721 #if defined(ENABLE_THREADS)
1727 /* Addresses are 31 bit integers */
1728 # define ADDR_MASK(x) (void *) ((uintptr_t) (x) & 0x7FFFFFFF)
1730 # define ADDR_MASK(x) (x)
1733 xptr = LLNI_WRAP(xptro);
1734 xpc = ADDR_MASK(xpc);
1736 /* Fill and add a stackframeinfo (XPC is equal to RA). */
1738 stacktrace_stackframeinfo_add(&sfi, pv, sp, xpc, xpc);
1742 /* Get the codeinfo for the current method. */
1744 code = code_get_codeinfo_for_pv(pv);
1746 /* Get the methodinfo pointer from the codeinfo pointer. For
1747 asm_vm_call_method the codeinfo pointer is NULL and we simply
1748 can return the proper exception handler. */
1751 result = (void *) (uintptr_t) &asm_vm_call_method_exception_handler;
1752 goto exceptions_handle_exception_return;
1757 #if !defined(NDEBUG)
1758 /* print exception trace */
1760 if (opt_TraceExceptions)
1761 trace_exception(LLNI_DIRECT(xptr), m, xpc);
1763 # if defined(ENABLE_VMLOG)
1764 vmlog_cacao_throw(xptr);
1768 /* Get the exception table. */
1770 et = code->exceptiontable;
1773 /* Iterate over all exception table entries. */
1777 for (i = 0; i < et->length; i++, ete++) {
1778 /* is the xpc is the current catch range */
1780 if ((ADDR_MASK(ete->startpc) <= xpc) && (xpc < ADDR_MASK(ete->endpc))) {
1781 cr = ete->catchtype;
1783 /* NULL catches everything */
1785 if (cr.any == NULL) {
1786 #if !defined(NDEBUG)
1787 /* Print stacktrace of exception when caught. */
1789 # if defined(ENABLE_VMLOG)
1790 vmlog_cacao_catch(xptr);
1793 if (opt_TraceExceptions) {
1794 exceptions_print_exception(xptr);
1795 stacktrace_print_trace(xptr);
1799 result = ete->handlerpc;
1800 goto exceptions_handle_exception_return;
1803 /* resolve or load/link the exception class */
1805 if (IS_CLASSREF(cr)) {
1806 /* The exception class reference is unresolved. */
1807 /* We have to do _eager_ resolving here. While the
1808 class of the exception object is guaranteed to be
1809 loaded, it may well have been loaded by a different
1810 loader than the defining loader of m's class, which
1811 is the one we must use to resolve the catch
1812 class. Thus lazy resolving might fail, even if the
1813 result of the resolution would be an already loaded
1816 c = resolve_classref_eager(cr.ref);
1819 /* Exception resolving the exception class, argh! */
1820 goto exceptions_handle_exception_return;
1823 /* Ok, we resolved it. Enter it in the table, so we
1824 don't have to do this again. */
1825 /* XXX this write should be atomic. Is it? */
1827 ete->catchtype.cls = c;
1832 /* XXX I don't think this case can ever happen. -Edwin */
1833 if (!(c->state & CLASS_LOADED))
1834 /* use the methods' classloader */
1835 if (!load_class_from_classloader(c->name,
1836 m->class->classloader))
1837 goto exceptions_handle_exception_return;
1839 /* XXX I think, if it is not linked, we can be sure
1840 that the exception object is no (indirect) instance
1841 of it, no? -Edwin */
1842 if (!(c->state & CLASS_LINKED))
1844 goto exceptions_handle_exception_return;
1847 /* is the thrown exception an instance of the catch class? */
1849 if (builtin_instanceof(xptr, c)) {
1850 #if !defined(NDEBUG)
1851 /* Print stacktrace of exception when caught. */
1853 # if defined(ENABLE_VMLOG)
1854 vmlog_cacao_catch(xptr);
1857 if (opt_TraceExceptions) {
1858 exceptions_print_exception(xptr);
1859 stacktrace_print_trace(xptr);
1863 result = ete->handlerpc;
1864 goto exceptions_handle_exception_return;
1870 #if defined(ENABLE_THREADS)
1871 /* Is this method realization synchronized? */
1873 if (code_is_synchronized(code)) {
1874 /* Get synchronization object. */
1876 o = *((java_object_t **) (((uintptr_t) sp) + code->synchronizedoffset));
1880 lock_monitor_exit(LLNI_QUICKWRAP(o));
1884 /* none of the exceptions catch this one */
1886 #if !defined(NDEBUG)
1887 # if defined(ENABLE_VMLOG)
1888 vmlog_cacao_unwnd_method(m);
1891 # if defined(ENABLE_DEBUG_FILTER)
1892 if (show_filters_test_verbosecall_exit(m)) {
1895 /* outdent the log message */
1897 if (opt_verbosecall) {
1898 if (TRACEJAVACALLINDENT)
1899 TRACEJAVACALLINDENT--;
1901 log_text("exceptions_handle_exception: WARNING: unmatched unindent");
1904 # if defined(ENABLE_DEBUG_FILTER)
1907 #endif /* !defined(NDEBUG) */
1911 exceptions_handle_exception_return:
1913 /* Remove the stackframeinfo. */
1915 stacktrace_stackframeinfo_remove(&sfi);
1919 #endif /* defined(ENABLE_JIT) */
1922 /* exceptions_print_exception **************************************************
1924 Prints an exception, the detail message and the cause, if
1925 available, with CACAO internal functions to stdout.
1927 *******************************************************************************/
1929 void exceptions_print_exception(java_handle_t *xptr)
1931 java_lang_Throwable *t;
1932 #if defined(ENABLE_JAVASE)
1933 java_lang_Throwable *cause;
1935 java_lang_String *s;
1939 t = (java_lang_Throwable *) xptr;
1946 #if defined(ENABLE_JAVASE)
1947 LLNI_field_get_ref(t, cause, cause);
1950 /* print the root exception */
1952 LLNI_class_get(t, c);
1953 utf_display_printable_ascii_classname(c->name);
1955 LLNI_field_get_ref(t, detailMessage, s);
1958 u = javastring_toutf((java_handle_t *) s, false);
1961 utf_display_printable_ascii(u);
1966 #if defined(ENABLE_JAVASE)
1967 /* print the cause if available */
1969 if ((cause != NULL) && (cause != t)) {
1970 printf("Caused by: ");
1972 LLNI_class_get(cause, c);
1973 utf_display_printable_ascii_classname(c->name);
1975 LLNI_field_get_ref(cause, detailMessage, s);
1978 u = javastring_toutf((java_handle_t *) s, false);
1981 utf_display_printable_ascii(u);
1990 /* exceptions_print_current_exception ******************************************
1992 Prints the current pending exception, the detail message and the
1993 cause, if available, with CACAO internal functions to stdout.
1995 *******************************************************************************/
1997 void exceptions_print_current_exception(void)
2001 o = exceptions_get_exception();
2003 exceptions_print_exception(o);
2007 /* exceptions_print_stacktrace *************************************************
2009 Prints a pending exception with Throwable.printStackTrace(). If
2010 there happens an exception during printStackTrace(), we print the
2011 thrown exception and the original one.
2013 NOTE: This function calls Java code.
2015 *******************************************************************************/
2017 void exceptions_print_stacktrace(void)
2019 java_handle_t *oxptr;
2020 java_handle_t *xptr;
2024 /* get original exception */
2026 oxptr = exceptions_get_and_clear_exception();
2029 vm_abort("exceptions_print_stacktrace: no exception thrown");
2031 /* clear exception, because we are calling jit code again */
2033 LLNI_class_get(oxptr, c);
2035 /* find the printStackTrace() method */
2037 m = class_resolveclassmethod(c,
2038 utf_printStackTrace,
2040 class_java_lang_Object,
2044 vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
2046 /* print compatibility message */
2048 fprintf(stderr, "Exception in thread \"main\" ");
2050 /* print the stacktrace */
2052 (void) vm_call_method(m, oxptr);
2054 /* This normally means, we are EXTREMLY out of memory or
2055 have a serious problem while printStackTrace. But may
2056 be another exception, so print it. */
2058 xptr = exceptions_get_exception();
2061 fprintf(stderr, "Exception while printStackTrace(): ");
2063 /* now print original exception */
2065 exceptions_print_exception(xptr);
2066 stacktrace_print_trace(xptr);
2068 /* now print original exception */
2070 fprintf(stderr, "Original exception was: ");
2071 exceptions_print_exception(oxptr);
2072 stacktrace_print_trace(oxptr);
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: