1 /* src/vm/exceptions.c - 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 "native/include/java_lang_String.h"
45 #include "native/include/java_lang_Throwable.h"
47 #include "threads/lock-common.h"
48 #include "threads/threads-common.h"
50 #include "toolbox/util.h"
52 #include "vm/builtin.h"
53 #include "vm/exceptions.h"
54 #include "vm/global.h"
55 #include "vm/stringlocal.h"
58 #include "vm/jit/asmpart.h"
59 #include "vm/jit/jit.h"
60 #include "vm/jit/methodheader.h"
61 #include "vm/jit/patcher-common.h"
62 #include "vm/jit/show.h"
63 #include "vm/jit/stacktrace.h"
64 #include "vm/jit/trace.h"
66 #include "vmcore/class.h"
67 #include "vmcore/loader.h"
68 #include "vmcore/method.h"
69 #include "vmcore/options.h"
70 #include "vmcore/system.h"
72 #if defined(ENABLE_VMLOG)
73 #include <vmlog_cacao.h>
77 /* for raising exceptions from native methods *********************************/
79 #if !defined(ENABLE_THREADS)
80 java_object_t *_no_threads_exceptionptr = NULL;
84 /* exceptions_init *************************************************************
86 Initialize the exceptions subsystem.
88 *******************************************************************************/
90 void exceptions_init(void)
92 #if !(defined(__ARM__) && defined(__LINUX__))
93 /* On arm-linux the first memory page can't be mmap'ed, as it
94 contains the exception vectors. */
98 /* mmap a memory page at address 0x0, so our hardware-exceptions
101 pagesize = system_getpagesize();
103 (void) system_mmap_anonymous(NULL, pagesize, PROT_NONE, MAP_PRIVATE | MAP_FIXED);
106 TRACESUBSYSTEMINITIALIZATION("exceptions_init");
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_class_utf ****************************************************
281 Creates an exception object with the given class and initalizes it
282 with the given utf message.
285 c ......... exception class
286 message ... the message as an utf *
289 an exception pointer (in any case -- either it is the newly
290 created exception, or an exception thrown while trying to create
293 *******************************************************************************/
295 static java_handle_t *exceptions_new_class_utf(classinfo *c, utf *message)
301 exceptions_abort(c->name, message);
303 s = javastring_new(message);
306 return exceptions_get_exception();
308 o = native_new_and_init_string(c, s);
311 return exceptions_get_exception();
317 /* exceptions_new_utf **********************************************************
319 Creates an exception object with the given name and initalizes it.
322 classname....class name in UTF-8
324 *******************************************************************************/
326 static java_handle_t *exceptions_new_utf(utf *classname)
332 exceptions_abort(classname, NULL);
334 c = load_class_bootstrap(classname);
337 return exceptions_get_exception();
339 o = native_new_and_init(c);
342 return exceptions_get_exception();
348 /* exceptions_new_utf_javastring ***********************************************
350 Creates an exception object with the given name and initalizes it
351 with the given java/lang/String message.
354 classname....class name in UTF-8
355 message......the message as a java.lang.String
358 an exception pointer (in any case -- either it is the newly created
359 exception, or an exception thrown while trying to create it).
361 *******************************************************************************/
363 static java_handle_t *exceptions_new_utf_javastring(utf *classname,
364 java_handle_t *message)
370 exceptions_abort(classname, NULL);
372 c = load_class_bootstrap(classname);
375 return exceptions_get_exception();
377 o = native_new_and_init_string(c, message);
380 return exceptions_get_exception();
386 /* exceptions_new_utf_utf ******************************************************
388 Creates an exception object with the given name and initalizes it
389 with the given utf message.
392 classname....class name in UTF-8
393 message......the message as an utf *
396 an exception pointer (in any case -- either it is the newly created
397 exception, or an exception thrown while trying to create it).
399 *******************************************************************************/
401 static java_handle_t *exceptions_new_utf_utf(utf *classname, utf *message)
407 exceptions_abort(classname, message);
409 c = load_class_bootstrap(classname);
412 return exceptions_get_exception();
414 o = exceptions_new_class_utf(c, message);
420 /* exceptions_throw_class_utf **************************************************
422 Creates an exception object with the given class, initalizes and
423 throws it with the given utf message.
426 c ......... exception class
427 message ... the message as an utf *
429 *******************************************************************************/
431 static void exceptions_throw_class_utf(classinfo *c, utf *message)
435 o = exceptions_new_class_utf(c, message);
437 exceptions_set_exception(o);
441 /* exceptions_throw_utf ********************************************************
443 Creates an exception object with the given name, initalizes and
447 classname....class name in UTF-8
449 *******************************************************************************/
451 static void exceptions_throw_utf(utf *classname)
455 o = exceptions_new_utf(classname);
460 exceptions_set_exception(o);
464 /* exceptions_throw_utf_throwable **********************************************
466 Creates an exception object with the given name and initalizes it
467 with the given java/lang/Throwable exception.
470 classname....class name in UTF-8
471 cause........the given Throwable
473 *******************************************************************************/
475 static void exceptions_throw_utf_throwable(utf *classname,
476 java_handle_t *cause)
481 java_lang_Throwable *object;
484 exceptions_abort(classname, NULL);
486 object = (java_lang_Throwable *) cause;
488 c = load_class_bootstrap(classname);
500 /* call initializer */
502 m = class_resolveclassmethod(c,
504 utf_java_lang_Throwable__void,
511 (void) vm_call_method(m, o, cause);
513 exceptions_set_exception(o);
517 /* exceptions_throw_utf_exception **********************************************
519 Creates an exception object with the given name and initalizes it
520 with the given java/lang/Exception exception.
523 classname....class name in UTF-8
524 exception....the given Exception
526 *******************************************************************************/
528 static void exceptions_throw_utf_exception(utf *classname,
529 java_handle_t *exception)
536 exceptions_abort(classname, NULL);
538 c = load_class_bootstrap(classname);
550 /* call initializer */
552 m = class_resolveclassmethod(c,
554 utf_java_lang_Exception__V,
561 (void) vm_call_method(m, o, exception);
563 exceptions_set_exception(o);
567 /* exceptions_throw_utf_cause **************************************************
569 Creates an exception object with the given name and initalizes it
570 with the given java/lang/Throwable exception with initCause.
573 classname....class name in UTF-8
574 cause........the given Throwable
576 *******************************************************************************/
578 static void exceptions_throw_utf_cause(utf *classname, java_handle_t *cause)
584 java_lang_Throwable *object;
587 exceptions_abort(classname, NULL);
589 object = (java_lang_Throwable *) cause;
591 c = load_class_bootstrap(classname);
603 /* call initializer */
605 m = class_resolveclassmethod(c,
607 utf_java_lang_String__void,
614 LLNI_field_get_ref(object, detailMessage, s);
616 (void) vm_call_method(m, o, s);
620 m = class_resolveclassmethod(c,
622 utf_java_lang_Throwable__java_lang_Throwable,
629 (void) vm_call_method(m, o, cause);
631 exceptions_set_exception(o);
635 /* exceptions_throw_utf_utf ****************************************************
637 Creates an exception object with the given name, initalizes and
638 throws it with the given utf message.
641 classname....class name in UTF-8
642 message......the message as an utf *
644 *******************************************************************************/
646 static void exceptions_throw_utf_utf(utf *classname, utf *message)
650 o = exceptions_new_utf_utf(classname, message);
652 exceptions_set_exception(o);
656 /* exceptions_new_abstractmethoderror ****************************************
658 Generates a java.lang.AbstractMethodError for the VM.
660 *******************************************************************************/
662 java_handle_t *exceptions_new_abstractmethoderror(void)
666 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
672 /* exceptions_new_error ********************************************************
674 Generates a java.lang.Error for the VM.
676 *******************************************************************************/
678 #if defined(ENABLE_JAVAME_CLDC1_1)
679 static java_handle_t *exceptions_new_error(utf *message)
683 o = exceptions_new_utf_utf(utf_java_lang_Error, message);
690 /* exceptions_asm_new_abstractmethoderror **************************************
692 Generates a java.lang.AbstractMethodError for
693 asm_abstractmethoderror.
695 *******************************************************************************/
697 java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
699 stackframeinfo_t sfi;
703 /* Fill and add a stackframeinfo (XPC is equal to RA). */
705 stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra);
707 /* create the exception */
709 #if defined(ENABLE_JAVASE)
710 e = exceptions_new_abstractmethoderror();
712 e = exceptions_new_error(utf_java_lang_AbstractMethodError);
715 /* Remove the stackframeinfo. */
717 stacktrace_stackframeinfo_remove(&sfi);
719 /* unwrap the exception */
720 /* ATTENTION: do the this _after_ the stackframeinfo was removed */
728 /* exceptions_new_arraystoreexception ******************************************
730 Generates a java.lang.ArrayStoreException for the VM.
732 *******************************************************************************/
734 java_handle_t *exceptions_new_arraystoreexception(void)
738 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
744 /* exceptions_throw_abstractmethoderror ****************************************
746 Generates and throws a java.lang.AbstractMethodError for the VM.
748 *******************************************************************************/
750 void exceptions_throw_abstractmethoderror(void)
752 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
756 /* exceptions_throw_classcircularityerror **************************************
758 Generates and throws a java.lang.ClassCircularityError for the
762 c....the class in which the error was found
764 *******************************************************************************/
766 void exceptions_throw_classcircularityerror(classinfo *c)
768 exceptions_throw_utf_utf(utf_java_lang_ClassCircularityError, c->name);
772 /* exceptions_throw_classformaterror *******************************************
774 Generates and throws a java.lang.ClassFormatError for the VM.
777 c............the class in which the error was found
778 message......UTF-8 format string
780 *******************************************************************************/
782 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
789 /* calculate message length */
794 msglen += utf_bytes(c->name) + strlen(" (");
796 va_start(ap, message);
797 msglen += get_variable_message_length(message, ap);
801 msglen += strlen(")");
803 msglen += strlen("0");
805 /* allocate a buffer */
807 msg = MNEW(char, msglen);
809 /* print message into allocated buffer */
812 utf_copy_classname(msg, c->name);
816 va_start(ap, message);
817 vsprintf(msg + strlen(msg), message, ap);
823 u = utf_new_char(msg);
827 MFREE(msg, char, msglen);
829 /* throw exception */
831 exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
835 /* exceptions_throw_classnotfoundexception *************************************
837 Generates and throws a java.lang.ClassNotFoundException for the
841 name.........name of the class not found as a utf *
843 *******************************************************************************/
845 void exceptions_throw_classnotfoundexception(utf *name)
847 exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
851 /* exceptions_throw_noclassdeffounderror ***************************************
853 Generates and throws a java.lang.NoClassDefFoundError.
856 name.........name of the class not found as a utf *
858 *******************************************************************************/
860 void exceptions_throw_noclassdeffounderror(utf *name)
862 exceptions_throw_utf_utf(utf_java_lang_NoClassDefFoundError, name);
866 /* exceptions_throw_noclassdeffounderror_cause *********************************
868 Generates and throws a java.lang.NoClassDefFoundError with the
871 *******************************************************************************/
873 void exceptions_throw_noclassdeffounderror_cause(java_handle_t *cause)
875 exceptions_throw_utf_cause(utf_java_lang_NoClassDefFoundError, cause);
879 /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
881 Generates and throws a java.lang.NoClassDefFoundError with a
885 name.........name of the class not found as a utf *
887 *******************************************************************************/
889 void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
895 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
896 utf_bytes(name) + strlen(")") + strlen("0");
898 msg = MNEW(char, msglen);
900 utf_copy_classname(msg, c->name);
901 strcat(msg, " (wrong name: ");
902 utf_cat_classname(msg, name);
905 u = utf_new_char(msg);
907 MFREE(msg, char, msglen);
909 exceptions_throw_noclassdeffounderror(u);
913 /* exceptions_throw_exceptionininitializererror ********************************
915 Generates and throws a java.lang.ExceptionInInitializerError for
919 cause......cause exception object
921 *******************************************************************************/
923 void exceptions_throw_exceptionininitializererror(java_handle_t *cause)
925 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
930 /* exceptions_throw_incompatibleclasschangeerror *******************************
932 Generates and throws a java.lang.IncompatibleClassChangeError for
936 message......UTF-8 message format string
938 *******************************************************************************/
940 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
946 /* calculate exception message length */
948 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
950 /* allocate memory */
952 msg = MNEW(char, msglen);
954 utf_copy_classname(msg, c->name);
955 strcat(msg, message);
957 u = utf_new_char(msg);
961 MFREE(msg, char, msglen);
963 /* throw exception */
965 exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
969 /* exceptions_throw_instantiationerror *****************************************
971 Generates and throws a java.lang.InstantiationError for the VM.
973 *******************************************************************************/
975 void exceptions_throw_instantiationerror(classinfo *c)
977 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
981 /* exceptions_throw_internalerror **********************************************
983 Generates and throws a java.lang.InternalError for the VM.
986 message......UTF-8 message format string
988 *******************************************************************************/
990 void exceptions_throw_internalerror(const char *message, ...)
997 /* calculate exception message length */
999 va_start(ap, message);
1000 msglen = get_variable_message_length(message, ap);
1003 /* allocate memory */
1005 msg = MNEW(char, msglen);
1007 /* generate message */
1009 va_start(ap, message);
1010 vsprintf(msg, message, ap);
1013 u = utf_new_char(msg);
1017 MFREE(msg, char, msglen);
1019 /* throw exception */
1021 exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
1025 /* exceptions_throw_linkageerror ***********************************************
1027 Generates and throws java.lang.LinkageError with an error message.
1030 message......UTF-8 message
1031 c............class related to the error. If this is != NULL
1032 the name of c is appended to the error message.
1034 *******************************************************************************/
1036 void exceptions_throw_linkageerror(const char *message, classinfo *c)
1042 /* calculate exception message length */
1044 len = strlen(message) + 1;
1047 len += utf_bytes(c->name);
1049 /* allocate memory */
1051 msg = MNEW(char, len);
1053 /* generate message */
1055 strcpy(msg, message);
1058 utf_cat_classname(msg, c->name);
1060 u = utf_new_char(msg);
1064 MFREE(msg, char, len);
1066 exceptions_throw_utf_utf(utf_java_lang_LinkageError, u);
1070 /* exceptions_throw_nosuchfielderror *******************************************
1072 Generates and throws a java.lang.NoSuchFieldError with an error
1076 c............class in which the field was not found
1077 name.........name of the field
1079 *******************************************************************************/
1081 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
1087 /* calculate exception message length */
1089 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
1091 /* allocate memory */
1093 msg = MNEW(char, msglen);
1095 /* generate message */
1097 utf_copy_classname(msg, c->name);
1101 u = utf_new_char(msg);
1105 MFREE(msg, char, msglen);
1107 exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
1111 /* exceptions_throw_nosuchmethoderror ******************************************
1113 Generates and throws a java.lang.NoSuchMethodError with an error
1117 c............class in which the method was not found
1118 name.........name of the method
1119 desc.........descriptor of the method
1121 *******************************************************************************/
1123 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
1129 /* calculate exception message length */
1131 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
1132 utf_bytes(desc) + strlen("0");
1134 /* allocate memory */
1136 msg = MNEW(char, msglen);
1138 /* generate message */
1140 utf_copy_classname(msg, c->name);
1145 u = utf_new_char(msg);
1149 MFREE(msg, char, msglen);
1151 #if defined(ENABLE_JAVASE)
1152 exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
1154 exceptions_throw_utf_utf(utf_java_lang_Error, u);
1159 /* exceptions_throw_outofmemoryerror *******************************************
1161 Generates and throws an java.lang.OutOfMemoryError for the VM.
1163 *******************************************************************************/
1165 void exceptions_throw_outofmemoryerror(void)
1167 exceptions_throw_utf(utf_java_lang_OutOfMemoryError);
1171 /* exceptions_throw_unsatisfiedlinkerror ***************************************
1173 Generates and throws a java.lang.UnsatisfiedLinkError for the
1177 name......UTF-8 name string
1179 *******************************************************************************/
1181 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1183 #if defined(ENABLE_JAVASE)
1184 exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1186 exceptions_throw_utf_utf(utf_java_lang_Error, name);
1191 /* exceptions_throw_unsupportedclassversionerror *******************************
1193 Generates and throws a java.lang.UnsupportedClassVersionError for
1197 c............class in which the method was not found
1198 message......UTF-8 format string
1200 *******************************************************************************/
1202 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1208 /* calculate exception message length */
1211 utf_bytes(c->name) +
1212 strlen(" (Unsupported major.minor version 00.0)") +
1215 /* allocate memory */
1217 msg = MNEW(char, msglen);
1219 /* generate message */
1221 utf_copy_classname(msg, c->name);
1222 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1225 u = utf_new_char(msg);
1229 MFREE(msg, char, msglen);
1231 /* throw exception */
1233 exceptions_throw_utf_utf(utf_java_lang_UnsupportedClassVersionError, u);
1237 /* exceptions_throw_verifyerror ************************************************
1239 Generates and throws a java.lang.VerifyError for the JIT compiler.
1242 m............method in which the error was found
1243 message......UTF-8 format string
1245 *******************************************************************************/
1247 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1254 /* calculate exception message length */
1260 strlen("(class: ") + utf_bytes(m->class->name) +
1261 strlen(", method: ") + utf_bytes(m->name) +
1262 strlen(" signature: ") + utf_bytes(m->descriptor) +
1263 strlen(") ") + strlen("0");
1265 va_start(ap, message);
1266 msglen += get_variable_message_length(message, ap);
1269 /* allocate memory */
1271 msg = MNEW(char, msglen);
1273 /* generate message */
1276 strcpy(msg, "(class: ");
1277 utf_cat_classname(msg, m->class->name);
1278 strcat(msg, ", method: ");
1279 utf_cat(msg, m->name);
1280 strcat(msg, " signature: ");
1281 utf_cat(msg, m->descriptor);
1285 va_start(ap, message);
1286 vsprintf(msg + strlen(msg), message, ap);
1289 u = utf_new_char(msg);
1293 MFREE(msg, char, msglen);
1295 /* throw exception */
1297 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1301 /* exceptions_throw_verifyerror_for_stack **************************************
1303 throws a java.lang.VerifyError for an invalid stack slot type
1306 m............method in which the error was found
1307 type.........the expected type
1310 an exception pointer (in any case -- either it is the newly created
1311 exception, or an exception thrown while trying to create it).
1313 *******************************************************************************/
1315 void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
1322 /* calculate exception message length */
1327 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1328 strlen(", method: ") + utf_bytes(m->name) +
1329 strlen(" signature: ") + utf_bytes(m->descriptor) +
1330 strlen(") Expecting to find longest-------typename on stack")
1333 /* allocate memory */
1335 msg = MNEW(char, msglen);
1337 /* generate message */
1340 strcpy(msg, "(class: ");
1341 utf_cat_classname(msg, m->class->name);
1342 strcat(msg, ", method: ");
1343 utf_cat(msg, m->name);
1344 strcat(msg, " signature: ");
1345 utf_cat(msg, m->descriptor);
1352 strcat(msg, "Expecting to find ");
1355 case TYPE_INT: typename = "integer"; break;
1356 case TYPE_LNG: typename = "long"; break;
1357 case TYPE_FLT: typename = "float"; break;
1358 case TYPE_DBL: typename = "double"; break;
1359 case TYPE_ADR: typename = "object/array"; break;
1360 case TYPE_RET: typename = "returnAddress"; break;
1361 default: typename = "<INVALID>"; assert(0); break;
1364 strcat(msg, typename);
1365 strcat(msg, " on stack");
1367 u = utf_new_char(msg);
1371 MFREE(msg, char, msglen);
1373 /* throw exception */
1375 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1379 /* exceptions_new_arithmeticexception ******************************************
1381 Generates a java.lang.ArithmeticException for the JIT compiler.
1383 *******************************************************************************/
1385 java_handle_t *exceptions_new_arithmeticexception(void)
1389 o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
1390 utf_division_by_zero);
1396 /* exceptions_new_arrayindexoutofboundsexception *******************************
1398 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1401 *******************************************************************************/
1403 java_handle_t *exceptions_new_arrayindexoutofboundsexception(s4 index)
1409 /* convert the index into a String, like Sun does */
1411 m = class_resolveclassmethod(class_java_lang_String,
1412 utf_new_char("valueOf"),
1413 utf_new_char("(I)Ljava/lang/String;"),
1414 class_java_lang_Object,
1418 return exceptions_get_exception();
1420 s = vm_call_method(m, NULL, index);
1423 return exceptions_get_exception();
1425 o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1429 return exceptions_get_exception();
1435 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1437 Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1440 *******************************************************************************/
1442 void exceptions_throw_arrayindexoutofboundsexception(void)
1444 exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1448 /* exceptions_throw_arraystoreexception ****************************************
1450 Generates and throws a java.lang.ArrayStoreException for the VM.
1452 *******************************************************************************/
1454 void exceptions_throw_arraystoreexception(void)
1456 exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1460 /* exceptions_new_classcastexception *******************************************
1462 Generates a java.lang.ClassCastException for the JIT compiler.
1464 *******************************************************************************/
1466 java_handle_t *exceptions_new_classcastexception(java_handle_t *o)
1472 LLNI_class_get(o, c);
1474 classname = c->name;
1476 e = exceptions_new_utf_utf(utf_java_lang_ClassCastException, classname);
1482 /* exceptions_throw_clonenotsupportedexception *********************************
1484 Generates and throws a java.lang.CloneNotSupportedException for the
1487 *******************************************************************************/
1489 void exceptions_throw_clonenotsupportedexception(void)
1491 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1495 /* exceptions_throw_illegalaccessexception *************************************
1497 Generates and throws a java.lang.IllegalAccessException for the VM.
1499 *******************************************************************************/
1501 void exceptions_throw_illegalaccessexception(utf *message)
1503 exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
1507 /* exceptions_throw_illegalargumentexception ***********************************
1509 Generates and throws a java.lang.IllegalArgumentException for the
1512 *******************************************************************************/
1514 void exceptions_throw_illegalargumentexception(void)
1516 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1520 /* exceptions_throw_illegalmonitorstateexception *******************************
1522 Generates and throws a java.lang.IllegalMonitorStateException for
1525 *******************************************************************************/
1527 void exceptions_throw_illegalmonitorstateexception(void)
1529 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1533 /* exceptions_throw_instantiationexception *************************************
1535 Generates and throws a java.lang.InstantiationException for the VM.
1537 *******************************************************************************/
1539 void exceptions_throw_instantiationexception(classinfo *c)
1541 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1545 /* exceptions_throw_interruptedexception ***************************************
1547 Generates and throws a java.lang.InterruptedException for the VM.
1549 *******************************************************************************/
1551 void exceptions_throw_interruptedexception(void)
1553 exceptions_throw_utf(utf_java_lang_InterruptedException);
1557 /* exceptions_throw_invocationtargetexception **********************************
1559 Generates and throws a java.lang.reflect.InvocationTargetException
1563 cause......cause exception object
1565 *******************************************************************************/
1567 void exceptions_throw_invocationtargetexception(java_handle_t *cause)
1569 exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1574 /* exceptions_throw_negativearraysizeexception *********************************
1576 Generates and throws a java.lang.NegativeArraySizeException for the
1579 *******************************************************************************/
1581 void exceptions_throw_negativearraysizeexception(void)
1583 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1587 /* exceptions_new_nullpointerexception *****************************************
1589 Generates a java.lang.NullPointerException for the VM system.
1591 *******************************************************************************/
1593 java_handle_t *exceptions_new_nullpointerexception(void)
1597 o = exceptions_new_utf(utf_java_lang_NullPointerException);
1603 /* exceptions_throw_nullpointerexception ***************************************
1605 Generates a java.lang.NullPointerException for the VM system and
1606 throw it in the VM system.
1608 *******************************************************************************/
1610 void exceptions_throw_nullpointerexception(void)
1612 exceptions_throw_utf(utf_java_lang_NullPointerException);
1616 /* exceptions_throw_privilegedactionexception **********************************
1618 Generates and throws a java.security.PrivilegedActionException.
1620 *******************************************************************************/
1622 void exceptions_throw_privilegedactionexception(java_handle_t *exception)
1624 exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
1629 /* exceptions_throw_stringindexoutofboundsexception ****************************
1631 Generates and throws a java.lang.StringIndexOutOfBoundsException
1634 *******************************************************************************/
1636 void exceptions_throw_stringindexoutofboundsexception(void)
1638 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1642 /* exceptions_fillinstacktrace *************************************************
1644 Calls the fillInStackTrace-method of the currently thrown
1647 *******************************************************************************/
1649 java_handle_t *exceptions_fillinstacktrace(void)
1657 o = exceptions_get_and_clear_exception();
1661 /* resolve methodinfo pointer from exception object */
1663 LLNI_class_get(o, c);
1665 #if defined(ENABLE_JAVASE)
1666 m = class_resolvemethod(c,
1667 utf_fillInStackTrace,
1668 utf_void__java_lang_Throwable);
1669 #elif defined(ENABLE_JAVAME_CLDC1_1)
1670 m = class_resolvemethod(c,
1671 utf_fillInStackTrace,
1674 #error IMPLEMENT ME!
1679 (void) vm_call_method(m, o);
1681 /* return exception object */
1687 /* exceptions_handle_exception *************************************************
1689 Try to find an exception handler for the given exception and return it.
1690 If no handler is found, exit the monitor of the method (if any)
1694 xptr.........the exception object
1695 xpc..........PC of where the exception was thrown
1696 pv...........Procedure Value of the current method
1697 sp...........current stack pointer
1700 the address of the first matching exception handler, or
1701 NULL if no handler was found
1703 *******************************************************************************/
1705 #if defined(ENABLE_JIT)
1706 void *exceptions_handle_exception(java_object_t *xptro, void *xpc, void *pv, void *sp)
1708 stackframeinfo_t sfi;
1709 java_handle_t *xptr;
1712 exceptiontable_t *et;
1713 exceptiontable_entry_t *ete;
1715 classref_or_classinfo cr;
1717 #if defined(ENABLE_THREADS)
1723 /* Addresses are 31 bit integers */
1724 # define ADDR_MASK(x) (void *) ((uintptr_t) (x) & 0x7FFFFFFF)
1726 # define ADDR_MASK(x) (x)
1729 xptr = LLNI_WRAP(xptro);
1730 xpc = ADDR_MASK(xpc);
1732 /* Fill and add a stackframeinfo (XPC is equal to RA). */
1734 stacktrace_stackframeinfo_add(&sfi, pv, sp, xpc, xpc);
1738 /* Get the codeinfo for the current method. */
1740 code = code_get_codeinfo_for_pv(pv);
1742 /* Get the methodinfo pointer from the codeinfo pointer. For
1743 asm_vm_call_method the codeinfo pointer is NULL and we simply
1744 can return the proper exception handler. */
1747 result = (void *) (uintptr_t) &asm_vm_call_method_exception_handler;
1748 goto exceptions_handle_exception_return;
1753 #if !defined(NDEBUG)
1754 /* print exception trace */
1756 if (opt_TraceExceptions)
1757 trace_exception(LLNI_DIRECT(xptr), m, xpc);
1759 # if defined(ENABLE_VMLOG)
1760 vmlog_cacao_throw(xptr);
1764 /* Get the exception table. */
1766 et = code->exceptiontable;
1769 /* Iterate over all exception table entries. */
1773 for (i = 0; i < et->length; i++, ete++) {
1774 /* is the xpc is the current catch range */
1776 if ((ADDR_MASK(ete->startpc) <= xpc) && (xpc < ADDR_MASK(ete->endpc))) {
1777 cr = ete->catchtype;
1779 /* NULL catches everything */
1781 if (cr.any == NULL) {
1782 #if !defined(NDEBUG)
1783 /* Print stacktrace of exception when caught. */
1785 # if defined(ENABLE_VMLOG)
1786 vmlog_cacao_catch(xptr);
1789 if (opt_TraceExceptions) {
1790 exceptions_print_exception(xptr);
1791 stacktrace_print_exception(xptr);
1795 result = ete->handlerpc;
1796 goto exceptions_handle_exception_return;
1799 /* resolve or load/link the exception class */
1801 if (IS_CLASSREF(cr)) {
1802 /* The exception class reference is unresolved. */
1803 /* We have to do _eager_ resolving here. While the
1804 class of the exception object is guaranteed to be
1805 loaded, it may well have been loaded by a different
1806 loader than the defining loader of m's class, which
1807 is the one we must use to resolve the catch
1808 class. Thus lazy resolving might fail, even if the
1809 result of the resolution would be an already loaded
1812 c = resolve_classref_eager(cr.ref);
1815 /* Exception resolving the exception class, argh! */
1816 goto exceptions_handle_exception_return;
1819 /* Ok, we resolved it. Enter it in the table, so we
1820 don't have to do this again. */
1821 /* XXX this write should be atomic. Is it? */
1823 ete->catchtype.cls = c;
1828 /* XXX I don't think this case can ever happen. -Edwin */
1829 if (!(c->state & CLASS_LOADED))
1830 /* use the methods' classloader */
1831 if (!load_class_from_classloader(c->name,
1832 m->class->classloader))
1833 goto exceptions_handle_exception_return;
1835 /* XXX I think, if it is not linked, we can be sure
1836 that the exception object is no (indirect) instance
1837 of it, no? -Edwin */
1838 if (!(c->state & CLASS_LINKED))
1840 goto exceptions_handle_exception_return;
1843 /* is the thrown exception an instance of the catch class? */
1845 if (builtin_instanceof(xptr, c)) {
1846 #if !defined(NDEBUG)
1847 /* Print stacktrace of exception when caught. */
1849 # if defined(ENABLE_VMLOG)
1850 vmlog_cacao_catch(xptr);
1853 if (opt_TraceExceptions) {
1854 exceptions_print_exception(xptr);
1855 stacktrace_print_exception(xptr);
1859 result = ete->handlerpc;
1860 goto exceptions_handle_exception_return;
1866 #if defined(ENABLE_THREADS)
1867 /* Is this method realization synchronized? */
1869 if (code_is_synchronized(code)) {
1870 /* Get synchronization object. */
1872 o = *((java_object_t **) (((uintptr_t) sp) + code->synchronizedoffset));
1876 lock_monitor_exit(LLNI_QUICKWRAP(o));
1880 /* none of the exceptions catch this one */
1882 #if !defined(NDEBUG)
1883 # if defined(ENABLE_VMLOG)
1884 vmlog_cacao_unwnd_method(m);
1887 # if defined(ENABLE_DEBUG_FILTER)
1888 if (show_filters_test_verbosecall_exit(m)) {
1891 /* outdent the log message */
1893 if (opt_verbosecall) {
1894 if (TRACEJAVACALLINDENT)
1895 TRACEJAVACALLINDENT--;
1897 log_text("exceptions_handle_exception: WARNING: unmatched unindent");
1900 # if defined(ENABLE_DEBUG_FILTER)
1903 #endif /* !defined(NDEBUG) */
1907 exceptions_handle_exception_return:
1909 /* Remove the stackframeinfo. */
1911 stacktrace_stackframeinfo_remove(&sfi);
1915 #endif /* defined(ENABLE_JIT) */
1918 /* exceptions_print_exception **************************************************
1920 Prints an exception, the detail message and the cause, if
1921 available, with CACAO internal functions to stdout.
1923 *******************************************************************************/
1925 void exceptions_print_exception(java_handle_t *xptr)
1927 java_lang_Throwable *t;
1928 #if defined(ENABLE_JAVASE)
1929 java_lang_Throwable *cause;
1931 java_lang_String *s;
1935 t = (java_lang_Throwable *) xptr;
1942 #if defined(ENABLE_JAVASE)
1943 LLNI_field_get_ref(t, cause, cause);
1946 /* print the root exception */
1948 LLNI_class_get(t, c);
1949 utf_display_printable_ascii_classname(c->name);
1951 LLNI_field_get_ref(t, detailMessage, s);
1954 u = javastring_toutf((java_handle_t *) s, false);
1957 utf_display_printable_ascii(u);
1962 #if defined(ENABLE_JAVASE)
1963 /* print the cause if available */
1965 if ((cause != NULL) && (cause != t)) {
1966 printf("Caused by: ");
1968 LLNI_class_get(cause, c);
1969 utf_display_printable_ascii_classname(c->name);
1971 LLNI_field_get_ref(cause, detailMessage, s);
1974 u = javastring_toutf((java_handle_t *) s, false);
1977 utf_display_printable_ascii(u);
1986 /* exceptions_print_current_exception ******************************************
1988 Prints the current pending exception, the detail message and the
1989 cause, if available, with CACAO internal functions to stdout.
1991 *******************************************************************************/
1993 void exceptions_print_current_exception(void)
1997 o = exceptions_get_exception();
1999 exceptions_print_exception(o);
2003 /* exceptions_print_stacktrace *************************************************
2005 Prints a pending exception with Throwable.printStackTrace(). If
2006 there happens an exception during printStackTrace(), we print the
2007 thrown exception and the original one.
2009 NOTE: This function calls Java code.
2011 *******************************************************************************/
2013 void exceptions_print_stacktrace(void)
2015 java_handle_t *oxptr;
2016 java_handle_t *xptr;
2020 /* get original exception */
2022 oxptr = exceptions_get_and_clear_exception();
2025 vm_abort("exceptions_print_stacktrace: no exception thrown");
2027 /* clear exception, because we are calling jit code again */
2029 LLNI_class_get(oxptr, c);
2031 /* find the printStackTrace() method */
2033 m = class_resolveclassmethod(c,
2034 utf_printStackTrace,
2036 class_java_lang_Object,
2040 vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
2042 /* print compatibility message */
2044 fprintf(stderr, "Exception in thread \"main\" ");
2046 /* print the stacktrace */
2048 (void) vm_call_method(m, oxptr);
2050 /* This normally means, we are EXTREMLY out of memory or
2051 have a serious problem while printStackTrace. But may
2052 be another exception, so print it. */
2054 xptr = exceptions_get_exception();
2057 fprintf(stderr, "Exception while printStackTrace(): ");
2059 /* now print original exception */
2061 exceptions_print_exception(xptr);
2062 stacktrace_print_exception(xptr);
2064 /* now print original exception */
2066 fprintf(stderr, "Original exception was: ");
2067 exceptions_print_exception(oxptr);
2068 stacktrace_print_exception(oxptr);
2076 * These are local overrides for various environment variables in Emacs.
2077 * Please do not remove this and leave it at the end of the file, where
2078 * Emacs will automagically detect them.
2079 * ---------------------------------------------------------------------
2082 * indent-tabs-mode: t
2086 * vim:noexpandtab:sw=4:ts=4: