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_Thread.h"
46 #include "native/include/java_lang_Throwable.h"
48 #include "threads/lock-common.h"
49 #include "threads/thread.hpp"
51 #include "toolbox/util.h"
53 #include "vm/builtin.h"
54 #include "vm/exceptions.hpp"
55 #include "vm/global.h"
56 #include "vm/string.hpp"
59 #include "vm/jit/asmpart.h"
60 #include "vm/jit/jit.h"
61 #include "vm/jit/methodheader.h"
62 #include "vm/jit/patcher-common.h"
63 #include "vm/jit/show.h"
64 #include "vm/jit/stacktrace.hpp"
65 #include "vm/jit/trace.hpp"
67 #include "vmcore/class.h"
68 #include "vmcore/globals.hpp"
69 #include "vmcore/loader.h"
70 #include "vmcore/method.h"
71 #include "vmcore/options.h"
72 #include "vmcore/os.hpp"
74 #if defined(ENABLE_VMLOG)
75 #include <vmlog_cacao.h>
82 /* for raising exceptions from native methods *********************************/
84 #if !defined(ENABLE_THREADS)
85 java_object_t *_no_threads_exceptionptr = NULL;
89 /* exceptions_get_exception ****************************************************
91 Returns the current exception pointer of the current thread.
93 *******************************************************************************/
95 java_handle_t *exceptions_get_exception(void)
99 #if defined(ENABLE_THREADS)
105 /* Get the exception. */
109 #if defined(ENABLE_THREADS)
110 o = t->_exceptionptr;
112 o = _no_threads_exceptionptr;
119 /* Return the exception. */
125 /* exceptions_set_exception ****************************************************
127 Sets the exception pointer of the current thread.
129 *******************************************************************************/
131 void exceptions_set_exception(java_handle_t *e)
136 #if defined(ENABLE_THREADS)
142 /* Set the exception. */
149 if (opt_DebugExceptions) {
150 printf("[exceptions_set_exception : t=%p, o=%p, class=",
151 (void *) t, (void *) o);
152 class_print(o->vftbl->clazz);
157 #if defined(ENABLE_THREADS)
158 t->_exceptionptr = o;
160 _no_threads_exceptionptr = o;
167 /* exceptions_clear_exception **************************************************
169 Clears the current exception pointer of the current thread.
171 *******************************************************************************/
173 void exceptions_clear_exception(void)
177 #if defined(ENABLE_THREADS)
183 /* Set the exception. */
186 if (opt_DebugExceptions) {
187 printf("[exceptions_clear_exception: t=%p]\n", (void *) t);
191 #if defined(ENABLE_THREADS)
192 t->_exceptionptr = NULL;
194 _no_threads_exceptionptr = NULL;
199 /* exceptions_get_and_clear_exception ******************************************
201 Gets the exception pointer of the current thread and clears it.
202 This function may return NULL.
204 *******************************************************************************/
206 java_handle_t *exceptions_get_and_clear_exception(void)
210 /* Get the exception... */
212 o = exceptions_get_exception();
214 /* ...and clear the exception if it is set. */
217 exceptions_clear_exception();
219 /* return the exception */
225 /* exceptions_abort ************************************************************
227 Prints exception to be thrown and aborts.
230 classname....class name
231 message......exception message
233 *******************************************************************************/
235 static void exceptions_abort(utf *classname, utf *message)
237 log_println("exception thrown while VM is initializing: ");
240 utf_display_printable_ascii_classname(classname);
242 if (message != NULL) {
244 utf_display_printable_ascii_classname(message);
249 vm_abort("Aborting...");
253 /* exceptions_new_class_utf ****************************************************
255 Creates an exception object with the given class and initalizes it
256 with the given utf message.
259 c ......... exception class
260 message ... the message as an utf *
263 an exception pointer (in any case -- either it is the newly
264 created exception, or an exception thrown while trying to create
267 *******************************************************************************/
269 static java_handle_t *exceptions_new_class_utf(classinfo *c, utf *message)
274 if (vm->is_initializing()) {
275 /* This can happen when global class variables are used which
276 are not initialized yet. */
279 exceptions_abort(NULL, message);
281 exceptions_abort(c->name, message);
284 s = javastring_new(message);
287 return exceptions_get_exception();
289 o = native_new_and_init_string(c, s);
292 return exceptions_get_exception();
298 /* exceptions_new_utf **********************************************************
300 Creates an exception object with the given name and initalizes it.
303 classname....class name in UTF-8
305 *******************************************************************************/
307 static java_handle_t *exceptions_new_utf(utf *classname)
312 if (vm->is_initializing())
313 exceptions_abort(classname, NULL);
315 c = load_class_bootstrap(classname);
318 return exceptions_get_exception();
320 o = native_new_and_init(c);
323 return exceptions_get_exception();
329 /* exceptions_new_utf_javastring ***********************************************
331 Creates an exception object with the given name and initalizes it
332 with the given java/lang/String message.
335 classname....class name in UTF-8
336 message......the message as a java.lang.String
339 an exception pointer (in any case -- either it is the newly created
340 exception, or an exception thrown while trying to create it).
342 *******************************************************************************/
344 static java_handle_t *exceptions_new_utf_javastring(utf *classname,
345 java_handle_t *message)
350 if (vm->is_initializing())
351 exceptions_abort(classname, NULL);
353 c = load_class_bootstrap(classname);
356 return exceptions_get_exception();
358 o = native_new_and_init_string(c, message);
361 return exceptions_get_exception();
367 /* exceptions_new_utf_utf ******************************************************
369 Creates an exception object with the given name and initalizes it
370 with the given utf message.
373 classname....class name in UTF-8
374 message......the message as an utf *
377 an exception pointer (in any case -- either it is the newly created
378 exception, or an exception thrown while trying to create it).
380 *******************************************************************************/
382 static java_handle_t *exceptions_new_utf_utf(utf *classname, utf *message)
387 if (vm->is_initializing())
388 exceptions_abort(classname, message);
390 c = load_class_bootstrap(classname);
393 return exceptions_get_exception();
395 o = exceptions_new_class_utf(c, message);
401 /* exceptions_throw_class_utf **************************************************
403 Creates an exception object with the given class, initalizes and
404 throws it with the given utf message.
407 c ......... exception class
408 message ... the message as an utf *
410 *******************************************************************************/
412 static void exceptions_throw_class_utf(classinfo *c, utf *message)
416 o = exceptions_new_class_utf(c, message);
418 exceptions_set_exception(o);
422 /* exceptions_throw_utf ********************************************************
424 Creates an exception object with the given name, initalizes and
428 classname....class name in UTF-8
430 *******************************************************************************/
432 static void exceptions_throw_utf(utf *classname)
436 o = exceptions_new_utf(classname);
441 exceptions_set_exception(o);
445 /* exceptions_throw_utf_throwable **********************************************
447 Creates an exception object with the given name and initalizes it
448 with the given java/lang/Throwable exception.
451 classname....class name in UTF-8
452 cause........the given Throwable
454 *******************************************************************************/
456 static void exceptions_throw_utf_throwable(utf *classname,
457 java_handle_t *cause)
462 java_lang_Throwable *object;
464 if (vm->is_initializing())
465 exceptions_abort(classname, NULL);
467 object = (java_lang_Throwable *) cause;
469 c = load_class_bootstrap(classname);
481 /* call initializer */
483 m = class_resolveclassmethod(c,
485 utf_java_lang_Throwable__void,
492 (void) vm_call_method(m, o, cause);
494 exceptions_set_exception(o);
498 /* exceptions_throw_utf_exception **********************************************
500 Creates an exception object with the given name and initalizes it
501 with the given java/lang/Exception exception.
504 classname....class name in UTF-8
505 exception....the given Exception
507 *******************************************************************************/
509 static void exceptions_throw_utf_exception(utf *classname,
510 java_handle_t *exception)
516 if (vm->is_initializing())
517 exceptions_abort(classname, NULL);
519 c = load_class_bootstrap(classname);
531 /* call initializer */
533 m = class_resolveclassmethod(c,
535 utf_java_lang_Exception__V,
542 (void) vm_call_method(m, o, exception);
544 exceptions_set_exception(o);
548 /* exceptions_throw_utf_cause **************************************************
550 Creates an exception object with the given name and initalizes it
551 with the given java/lang/Throwable exception with initCause.
554 classname....class name in UTF-8
555 cause........the given Throwable
557 *******************************************************************************/
559 static void exceptions_throw_utf_cause(utf *classname, java_handle_t *cause)
565 java_lang_Throwable *object;
567 if (vm->is_initializing())
568 exceptions_abort(classname, NULL);
570 object = (java_lang_Throwable *) cause;
572 c = load_class_bootstrap(classname);
584 /* call initializer */
586 m = class_resolveclassmethod(c,
588 utf_java_lang_String__void,
595 LLNI_field_get_ref(object, detailMessage, s);
597 (void) vm_call_method(m, o, s);
601 m = class_resolveclassmethod(c,
603 utf_java_lang_Throwable__java_lang_Throwable,
610 (void) vm_call_method(m, o, cause);
612 exceptions_set_exception(o);
616 /* exceptions_throw_utf_utf ****************************************************
618 Creates an exception object with the given name, initalizes and
619 throws it with the given utf message.
622 classname....class name in UTF-8
623 message......the message as an utf *
625 *******************************************************************************/
627 static void exceptions_throw_utf_utf(utf *classname, utf *message)
631 o = exceptions_new_utf_utf(classname, message);
633 exceptions_set_exception(o);
637 /* exceptions_new_abstractmethoderror ****************************************
639 Generates a java.lang.AbstractMethodError for the VM.
641 *******************************************************************************/
643 java_handle_t *exceptions_new_abstractmethoderror(void)
647 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
653 /* exceptions_new_error ********************************************************
655 Generates a java.lang.Error for the VM.
657 *******************************************************************************/
659 #if defined(ENABLE_JAVAME_CLDC1_1)
660 static java_handle_t *exceptions_new_error(utf *message)
664 o = exceptions_new_utf_utf(utf_java_lang_Error, message);
671 /* exceptions_asm_new_abstractmethoderror **************************************
673 Generates a java.lang.AbstractMethodError for
674 asm_abstractmethoderror.
676 *******************************************************************************/
678 java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
680 stackframeinfo_t sfi;
684 /* Fill and add a stackframeinfo (XPC is equal to RA). */
686 stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra);
688 /* create the exception */
690 #if defined(ENABLE_JAVASE)
691 e = exceptions_new_abstractmethoderror();
693 e = exceptions_new_error(utf_java_lang_AbstractMethodError);
696 /* Remove the stackframeinfo. */
698 stacktrace_stackframeinfo_remove(&sfi);
700 /* unwrap the exception */
701 /* ATTENTION: do the this _after_ the stackframeinfo was removed */
709 /* exceptions_new_arraystoreexception ******************************************
711 Generates a java.lang.ArrayStoreException for the VM.
713 *******************************************************************************/
715 java_handle_t *exceptions_new_arraystoreexception(void)
719 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
725 /* exceptions_throw_abstractmethoderror ****************************************
727 Generates and throws a java.lang.AbstractMethodError for the VM.
729 *******************************************************************************/
731 void exceptions_throw_abstractmethoderror(void)
733 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
737 /* exceptions_throw_classcircularityerror **************************************
739 Generates and throws a java.lang.ClassCircularityError for the
743 c....the class in which the error was found
745 *******************************************************************************/
747 void exceptions_throw_classcircularityerror(classinfo *c)
749 exceptions_throw_utf_utf(utf_java_lang_ClassCircularityError, c->name);
753 /* exceptions_throw_classformaterror *******************************************
755 Generates and throws a java.lang.ClassFormatError for the VM.
758 c............the class in which the error was found
759 message......UTF-8 format string
761 *******************************************************************************/
763 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
770 /* calculate message length */
775 msglen += utf_bytes(c->name) + strlen(" (");
777 va_start(ap, message);
778 msglen += get_variable_message_length(message, ap);
782 msglen += strlen(")");
784 msglen += strlen("0");
786 /* allocate a buffer */
788 msg = MNEW(char, msglen);
790 /* print message into allocated buffer */
793 utf_copy_classname(msg, c->name);
797 va_start(ap, message);
798 vsprintf(msg + strlen(msg), message, ap);
804 u = utf_new_char(msg);
808 MFREE(msg, char, msglen);
810 /* throw exception */
812 exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
816 /* exceptions_throw_classnotfoundexception *************************************
818 Generates and throws a java.lang.ClassNotFoundException for the
822 name.........name of the class not found as a utf *
824 *******************************************************************************/
826 void exceptions_throw_classnotfoundexception(utf *name)
828 exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
832 /* exceptions_throw_noclassdeffounderror ***************************************
834 Generates and throws a java.lang.NoClassDefFoundError.
837 name.........name of the class not found as a utf *
839 *******************************************************************************/
841 void exceptions_throw_noclassdeffounderror(utf *name)
843 exceptions_throw_utf_utf(utf_java_lang_NoClassDefFoundError, name);
847 /* exceptions_throw_noclassdeffounderror_cause *********************************
849 Generates and throws a java.lang.NoClassDefFoundError with the
852 *******************************************************************************/
854 void exceptions_throw_noclassdeffounderror_cause(java_handle_t *cause)
856 exceptions_throw_utf_cause(utf_java_lang_NoClassDefFoundError, cause);
860 /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
862 Generates and throws a java.lang.NoClassDefFoundError with a
866 name.........name of the class not found as a utf *
868 *******************************************************************************/
870 void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
876 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
877 utf_bytes(name) + strlen(")") + strlen("0");
879 msg = MNEW(char, msglen);
881 utf_copy_classname(msg, c->name);
882 strcat(msg, " (wrong name: ");
883 utf_cat_classname(msg, name);
886 u = utf_new_char(msg);
888 MFREE(msg, char, msglen);
890 exceptions_throw_noclassdeffounderror(u);
894 /* exceptions_throw_exceptionininitializererror ********************************
896 Generates and throws a java.lang.ExceptionInInitializerError for
900 cause......cause exception object
902 *******************************************************************************/
904 void exceptions_throw_exceptionininitializererror(java_handle_t *cause)
906 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
911 /* exceptions_throw_incompatibleclasschangeerror *******************************
913 Generates and throws a java.lang.IncompatibleClassChangeError for
917 message......UTF-8 message format string
919 *******************************************************************************/
921 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
927 /* calculate exception message length */
929 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
931 /* allocate memory */
933 msg = MNEW(char, msglen);
935 utf_copy_classname(msg, c->name);
936 strcat(msg, message);
938 u = utf_new_char(msg);
942 MFREE(msg, char, msglen);
944 /* throw exception */
946 exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
950 /* exceptions_throw_instantiationerror *****************************************
952 Generates and throws a java.lang.InstantiationError for the VM.
954 *******************************************************************************/
956 void exceptions_throw_instantiationerror(classinfo *c)
958 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
962 /* exceptions_throw_internalerror **********************************************
964 Generates and throws a java.lang.InternalError for the VM.
967 message......UTF-8 message format string
969 *******************************************************************************/
971 void exceptions_throw_internalerror(const char *message, ...)
978 /* calculate exception message length */
980 va_start(ap, message);
981 msglen = get_variable_message_length(message, ap);
984 /* allocate memory */
986 msg = MNEW(char, msglen);
988 /* generate message */
990 va_start(ap, message);
991 vsprintf(msg, message, ap);
994 u = utf_new_char(msg);
998 MFREE(msg, char, msglen);
1000 /* throw exception */
1002 exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
1006 /* exceptions_throw_linkageerror ***********************************************
1008 Generates and throws java.lang.LinkageError with an error message.
1011 message......UTF-8 message
1012 c............class related to the error. If this is != NULL
1013 the name of c is appended to the error message.
1015 *******************************************************************************/
1017 void exceptions_throw_linkageerror(const char *message, classinfo *c)
1023 /* calculate exception message length */
1025 len = strlen(message) + 1;
1028 len += utf_bytes(c->name);
1030 /* allocate memory */
1032 msg = MNEW(char, len);
1034 /* generate message */
1036 strcpy(msg, message);
1039 utf_cat_classname(msg, c->name);
1041 u = utf_new_char(msg);
1045 MFREE(msg, char, len);
1047 exceptions_throw_utf_utf(utf_java_lang_LinkageError, u);
1051 /* exceptions_throw_nosuchfielderror *******************************************
1053 Generates and throws a java.lang.NoSuchFieldError with an error
1057 c............class in which the field was not found
1058 name.........name of the field
1060 *******************************************************************************/
1062 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
1068 /* calculate exception message length */
1070 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
1072 /* allocate memory */
1074 msg = MNEW(char, msglen);
1076 /* generate message */
1078 utf_copy_classname(msg, c->name);
1082 u = utf_new_char(msg);
1086 MFREE(msg, char, msglen);
1088 exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
1092 /* exceptions_throw_nosuchmethoderror ******************************************
1094 Generates and throws a java.lang.NoSuchMethodError with an error
1098 c............class in which the method was not found
1099 name.........name of the method
1100 desc.........descriptor of the method
1102 *******************************************************************************/
1104 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
1110 /* calculate exception message length */
1112 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
1113 utf_bytes(desc) + strlen("0");
1115 /* allocate memory */
1117 msg = MNEW(char, msglen);
1119 /* generate message */
1121 utf_copy_classname(msg, c->name);
1126 u = utf_new_char(msg);
1130 MFREE(msg, char, msglen);
1132 #if defined(ENABLE_JAVASE)
1133 exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
1135 exceptions_throw_utf_utf(utf_java_lang_Error, u);
1140 /* exceptions_throw_outofmemoryerror *******************************************
1142 Generates and throws an java.lang.OutOfMemoryError for the VM.
1144 *******************************************************************************/
1146 void exceptions_throw_outofmemoryerror(void)
1148 exceptions_throw_utf(utf_java_lang_OutOfMemoryError);
1152 /* exceptions_throw_unsatisfiedlinkerror ***************************************
1154 Generates and throws a java.lang.UnsatisfiedLinkError for the
1158 name......UTF-8 name string
1160 *******************************************************************************/
1162 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1164 #if defined(ENABLE_JAVASE)
1165 exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1167 exceptions_throw_utf_utf(utf_java_lang_Error, name);
1172 /* exceptions_throw_unsupportedclassversionerror *******************************
1174 Generates and throws a java.lang.UnsupportedClassVersionError for
1178 c............class in which the method was not found
1179 message......UTF-8 format string
1181 *******************************************************************************/
1183 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1189 /* calculate exception message length */
1192 utf_bytes(c->name) +
1193 strlen(" (Unsupported major.minor version 00.0)") +
1196 /* allocate memory */
1198 msg = MNEW(char, msglen);
1200 /* generate message */
1202 utf_copy_classname(msg, c->name);
1203 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1206 u = utf_new_char(msg);
1210 MFREE(msg, char, msglen);
1212 /* throw exception */
1214 exceptions_throw_utf_utf(utf_java_lang_UnsupportedClassVersionError, u);
1218 /* exceptions_throw_verifyerror ************************************************
1220 Generates and throws a java.lang.VerifyError for the JIT compiler.
1223 m............method in which the error was found
1224 message......UTF-8 format string
1226 *******************************************************************************/
1228 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1235 /* calculate exception message length */
1241 strlen("(class: ") + utf_bytes(m->clazz->name) +
1242 strlen(", method: ") + utf_bytes(m->name) +
1243 strlen(" signature: ") + utf_bytes(m->descriptor) +
1244 strlen(") ") + strlen("0");
1246 va_start(ap, message);
1247 msglen += get_variable_message_length(message, ap);
1250 /* allocate memory */
1252 msg = MNEW(char, msglen);
1254 /* generate message */
1257 strcpy(msg, "(class: ");
1258 utf_cat_classname(msg, m->clazz->name);
1259 strcat(msg, ", method: ");
1260 utf_cat(msg, m->name);
1261 strcat(msg, " signature: ");
1262 utf_cat(msg, m->descriptor);
1266 va_start(ap, message);
1267 vsprintf(msg + strlen(msg), message, ap);
1270 u = utf_new_char(msg);
1274 MFREE(msg, char, msglen);
1276 /* throw exception */
1278 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1282 /* exceptions_throw_verifyerror_for_stack **************************************
1284 throws a java.lang.VerifyError for an invalid stack slot type
1287 m............method in which the error was found
1288 type.........the expected type
1291 an exception pointer (in any case -- either it is the newly created
1292 exception, or an exception thrown while trying to create it).
1294 *******************************************************************************/
1296 void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
1302 /* calculate exception message length */
1307 msglen = strlen("(class: ") + utf_bytes(m->clazz->name) +
1308 strlen(", method: ") + utf_bytes(m->name) +
1309 strlen(" signature: ") + utf_bytes(m->descriptor) +
1310 strlen(") Expecting to find longest-------typename on stack")
1313 /* allocate memory */
1315 msg = MNEW(char, msglen);
1317 /* generate message */
1320 strcpy(msg, "(class: ");
1321 utf_cat_classname(msg, m->clazz->name);
1322 strcat(msg, ", method: ");
1323 utf_cat(msg, m->name);
1324 strcat(msg, " signature: ");
1325 utf_cat(msg, m->descriptor);
1332 strcat(msg, "Expecting to find ");
1337 case TYPE_INT: name = "integer"; break;
1338 case TYPE_LNG: name = "long"; break;
1339 case TYPE_FLT: name = "float"; break;
1340 case TYPE_DBL: name = "double"; break;
1341 case TYPE_ADR: name = "object/array"; break;
1342 case TYPE_RET: name = "returnAddress"; break;
1343 default: name = "<INVALID>"; assert(0); break;
1347 strcat(msg, " on stack");
1349 u = utf_new_char(msg);
1353 MFREE(msg, char, msglen);
1355 /* throw exception */
1357 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1361 /* exceptions_new_arithmeticexception ******************************************
1363 Generates a java.lang.ArithmeticException for the JIT compiler.
1365 *******************************************************************************/
1367 java_handle_t *exceptions_new_arithmeticexception(void)
1371 o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
1372 utf_division_by_zero);
1378 /* exceptions_new_arrayindexoutofboundsexception *******************************
1380 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1383 *******************************************************************************/
1385 java_handle_t *exceptions_new_arrayindexoutofboundsexception(s4 index)
1391 /* convert the index into a String, like Sun does */
1393 m = class_resolveclassmethod(class_java_lang_String,
1394 utf_new_char("valueOf"),
1395 utf_new_char("(I)Ljava/lang/String;"),
1396 class_java_lang_Object,
1400 return exceptions_get_exception();
1402 s = vm_call_method(m, NULL, index);
1405 return exceptions_get_exception();
1407 o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1411 return exceptions_get_exception();
1417 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1419 Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1422 *******************************************************************************/
1424 void exceptions_throw_arrayindexoutofboundsexception(void)
1426 exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1430 /* exceptions_throw_arraystoreexception ****************************************
1432 Generates and throws a java.lang.ArrayStoreException for the VM.
1434 *******************************************************************************/
1436 void exceptions_throw_arraystoreexception(void)
1438 exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1442 /* exceptions_new_classcastexception *******************************************
1444 Generates a java.lang.ClassCastException for the JIT compiler.
1446 *******************************************************************************/
1448 java_handle_t *exceptions_new_classcastexception(java_handle_t *o)
1454 LLNI_class_get(o, c);
1456 classname = c->name;
1458 e = exceptions_new_utf_utf(utf_java_lang_ClassCastException, classname);
1464 /* exceptions_throw_clonenotsupportedexception *********************************
1466 Generates and throws a java.lang.CloneNotSupportedException for the
1469 *******************************************************************************/
1471 void exceptions_throw_clonenotsupportedexception(void)
1473 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1477 /* exceptions_throw_illegalaccessexception *************************************
1479 Generates and throws a java.lang.IllegalAccessException for the VM.
1481 *******************************************************************************/
1483 void exceptions_throw_illegalaccessexception(utf *message)
1485 exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
1489 /* exceptions_throw_illegalargumentexception ***********************************
1491 Generates and throws a java.lang.IllegalArgumentException for the
1494 *******************************************************************************/
1496 void exceptions_throw_illegalargumentexception(void)
1498 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1502 /* exceptions_throw_illegalmonitorstateexception *******************************
1504 Generates and throws a java.lang.IllegalMonitorStateException for
1507 *******************************************************************************/
1509 void exceptions_throw_illegalmonitorstateexception(void)
1511 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1515 /* exceptions_throw_instantiationexception *************************************
1517 Generates and throws a java.lang.InstantiationException for the VM.
1519 *******************************************************************************/
1521 void exceptions_throw_instantiationexception(classinfo *c)
1523 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1527 /* exceptions_throw_interruptedexception ***************************************
1529 Generates and throws a java.lang.InterruptedException for the VM.
1531 *******************************************************************************/
1533 void exceptions_throw_interruptedexception(void)
1535 exceptions_throw_utf(utf_java_lang_InterruptedException);
1539 /* exceptions_throw_invocationtargetexception **********************************
1541 Generates and throws a java.lang.reflect.InvocationTargetException
1545 cause......cause exception object
1547 *******************************************************************************/
1549 void exceptions_throw_invocationtargetexception(java_handle_t *cause)
1551 exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1556 /* exceptions_throw_negativearraysizeexception *********************************
1558 Generates and throws a java.lang.NegativeArraySizeException for the
1561 *******************************************************************************/
1563 void exceptions_throw_negativearraysizeexception(void)
1565 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1569 /* exceptions_new_nullpointerexception *****************************************
1571 Generates a java.lang.NullPointerException for the VM system.
1573 *******************************************************************************/
1575 java_handle_t *exceptions_new_nullpointerexception(void)
1579 o = exceptions_new_utf(utf_java_lang_NullPointerException);
1585 /* exceptions_throw_nullpointerexception ***************************************
1587 Generates a java.lang.NullPointerException for the VM system and
1588 throw it in the VM system.
1590 *******************************************************************************/
1592 void exceptions_throw_nullpointerexception(void)
1594 exceptions_throw_utf(utf_java_lang_NullPointerException);
1598 /* exceptions_throw_privilegedactionexception **********************************
1600 Generates and throws a java.security.PrivilegedActionException.
1602 *******************************************************************************/
1604 void exceptions_throw_privilegedactionexception(java_handle_t *exception)
1606 exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
1611 /* exceptions_throw_stringindexoutofboundsexception ****************************
1613 Generates and throws a java.lang.StringIndexOutOfBoundsException
1616 *******************************************************************************/
1618 void exceptions_throw_stringindexoutofboundsexception(void)
1620 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1624 /* exceptions_fillinstacktrace *************************************************
1626 Calls the fillInStackTrace-method of the currently thrown
1629 *******************************************************************************/
1631 java_handle_t *exceptions_fillinstacktrace(void)
1639 o = exceptions_get_and_clear_exception();
1643 /* resolve methodinfo pointer from exception object */
1645 LLNI_class_get(o, c);
1647 #if defined(ENABLE_JAVASE)
1648 m = class_resolvemethod(c,
1649 utf_fillInStackTrace,
1650 utf_void__java_lang_Throwable);
1651 #elif defined(ENABLE_JAVAME_CLDC1_1)
1652 m = class_resolvemethod(c,
1653 utf_fillInStackTrace,
1656 #error IMPLEMENT ME!
1661 (void) vm_call_method(m, o);
1663 /* return exception object */
1669 /* exceptions_handle_exception *************************************************
1671 Try to find an exception handler for the given exception and return it.
1672 If no handler is found, exit the monitor of the method (if any)
1676 xptr.........the exception object
1677 xpc..........PC of where the exception was thrown
1678 pv...........Procedure Value of the current method
1679 sp...........current stack pointer
1682 the address of the first matching exception handler, or
1683 NULL if no handler was found
1685 *******************************************************************************/
1687 #if defined(ENABLE_JIT)
1688 void *exceptions_handle_exception(java_object_t *xptro, void *xpc, void *pv, void *sp)
1690 stackframeinfo_t sfi;
1691 java_handle_t *xptr;
1694 exceptiontable_t *et;
1695 exceptiontable_entry_t *ete;
1697 classref_or_classinfo cr;
1699 #if defined(ENABLE_THREADS)
1705 /* Addresses are 31 bit integers */
1706 # define ADDR_MASK(x) (void *) ((uintptr_t) (x) & 0x7FFFFFFF)
1708 # define ADDR_MASK(x) (x)
1711 xptr = LLNI_WRAP(xptro);
1712 xpc = ADDR_MASK(xpc);
1714 /* Fill and add a stackframeinfo (XPC is equal to RA). */
1716 stacktrace_stackframeinfo_add(&sfi, pv, sp, xpc, xpc);
1720 /* Get the codeinfo for the current method. */
1722 code = code_get_codeinfo_for_pv(pv);
1724 /* Get the methodinfo pointer from the codeinfo pointer. For
1725 asm_vm_call_method the codeinfo pointer is NULL and we simply
1726 can return the proper exception handler. */
1729 result = (void *) (uintptr_t) &asm_vm_call_method_exception_handler;
1730 goto exceptions_handle_exception_return;
1735 #if !defined(NDEBUG)
1736 /* print exception trace */
1738 if (opt_TraceExceptions)
1739 trace_exception(LLNI_DIRECT(xptr), m, xpc);
1741 # if defined(ENABLE_VMLOG)
1742 vmlog_cacao_throw(xptr);
1746 /* Get the exception table. */
1748 et = code->exceptiontable;
1751 /* Iterate over all exception table entries. */
1755 for (i = 0; i < et->length; i++, ete++) {
1756 /* is the xpc is the current catch range */
1758 if ((ADDR_MASK(ete->startpc) <= xpc) && (xpc < ADDR_MASK(ete->endpc))) {
1759 cr = ete->catchtype;
1761 /* NULL catches everything */
1763 if (cr.any == NULL) {
1764 #if !defined(NDEBUG)
1765 /* Print stacktrace of exception when caught. */
1767 # if defined(ENABLE_VMLOG)
1768 vmlog_cacao_catch(xptr);
1771 if (opt_TraceExceptions) {
1772 exceptions_print_exception(xptr);
1773 stacktrace_print_exception(xptr);
1777 result = ete->handlerpc;
1778 goto exceptions_handle_exception_return;
1781 /* resolve or load/link the exception class */
1783 if (IS_CLASSREF(cr)) {
1784 /* The exception class reference is unresolved. */
1785 /* We have to do _eager_ resolving here. While the
1786 class of the exception object is guaranteed to be
1787 loaded, it may well have been loaded by a different
1788 loader than the defining loader of m's class, which
1789 is the one we must use to resolve the catch
1790 class. Thus lazy resolving might fail, even if the
1791 result of the resolution would be an already loaded
1794 c = resolve_classref_eager(cr.ref);
1797 /* Exception resolving the exception class, argh! */
1798 goto exceptions_handle_exception_return;
1801 /* Ok, we resolved it. Enter it in the table, so we
1802 don't have to do this again. */
1803 /* XXX this write should be atomic. Is it? */
1805 ete->catchtype.cls = c;
1810 /* XXX I don't think this case can ever happen. -Edwin */
1811 if (!(c->state & CLASS_LOADED))
1812 /* use the methods' classloader */
1813 if (!load_class_from_classloader(c->name,
1814 m->clazz->classloader))
1815 goto exceptions_handle_exception_return;
1817 /* XXX I think, if it is not linked, we can be sure
1818 that the exception object is no (indirect) instance
1819 of it, no? -Edwin */
1820 if (!(c->state & CLASS_LINKED))
1822 goto exceptions_handle_exception_return;
1825 /* is the thrown exception an instance of the catch class? */
1827 if (builtin_instanceof(xptr, c)) {
1828 #if !defined(NDEBUG)
1829 /* Print stacktrace of exception when caught. */
1831 # if defined(ENABLE_VMLOG)
1832 vmlog_cacao_catch(xptr);
1835 if (opt_TraceExceptions) {
1836 exceptions_print_exception(xptr);
1837 stacktrace_print_exception(xptr);
1841 result = ete->handlerpc;
1842 goto exceptions_handle_exception_return;
1848 #if defined(ENABLE_THREADS)
1849 /* Is this method realization synchronized? */
1851 if (code_is_synchronized(code)) {
1852 /* Get synchronization object. */
1854 o = *((java_object_t **) (((uintptr_t) sp) + code->synchronizedoffset));
1858 lock_monitor_exit(LLNI_QUICKWRAP(o));
1862 /* none of the exceptions catch this one */
1864 #if !defined(NDEBUG)
1865 # if defined(ENABLE_VMLOG)
1866 vmlog_cacao_unwnd_method(m);
1869 # if defined(ENABLE_DEBUG_FILTER)
1870 if (show_filters_test_verbosecall_exit(m)) {
1873 /* outdent the log message */
1875 if (opt_verbosecall) {
1876 if (TRACEJAVACALLINDENT)
1877 TRACEJAVACALLINDENT--;
1879 log_text("exceptions_handle_exception: WARNING: unmatched unindent");
1882 # if defined(ENABLE_DEBUG_FILTER)
1885 #endif /* !defined(NDEBUG) */
1889 exceptions_handle_exception_return:
1891 /* Remove the stackframeinfo. */
1893 stacktrace_stackframeinfo_remove(&sfi);
1897 #endif /* defined(ENABLE_JIT) */
1900 /* exceptions_print_exception **************************************************
1902 Prints an exception, the detail message and the cause, if
1903 available, with CACAO internal functions to stdout.
1905 *******************************************************************************/
1907 void exceptions_print_exception(java_handle_t *xptr)
1909 java_lang_Throwable *t;
1910 #if defined(ENABLE_JAVASE)
1911 java_lang_Throwable *cause;
1913 java_lang_String *s;
1917 t = (java_lang_Throwable *) xptr;
1924 #if defined(ENABLE_JAVASE)
1925 LLNI_field_get_ref(t, cause, cause);
1928 /* print the root exception */
1930 LLNI_class_get(t, c);
1931 utf_display_printable_ascii_classname(c->name);
1933 LLNI_field_get_ref(t, detailMessage, s);
1936 u = javastring_toutf((java_handle_t *) s, false);
1939 utf_display_printable_ascii(u);
1944 #if defined(ENABLE_JAVASE)
1945 /* print the cause if available */
1947 if ((cause != NULL) && (cause != t)) {
1948 printf("Caused by: ");
1950 LLNI_class_get(cause, c);
1951 utf_display_printable_ascii_classname(c->name);
1953 LLNI_field_get_ref(cause, detailMessage, s);
1956 u = javastring_toutf((java_handle_t *) s, false);
1959 utf_display_printable_ascii(u);
1968 /* exceptions_print_current_exception ******************************************
1970 Prints the current pending exception, the detail message and the
1971 cause, if available, with CACAO internal functions to stdout.
1973 *******************************************************************************/
1975 void exceptions_print_current_exception(void)
1979 o = exceptions_get_exception();
1981 exceptions_print_exception(o);
1985 /* exceptions_print_stacktrace *************************************************
1987 Prints a pending exception with Throwable.printStackTrace(). If
1988 there happens an exception during printStackTrace(), we print the
1989 thrown exception and the original one.
1991 NOTE: This function calls Java code.
1993 *******************************************************************************/
1995 void exceptions_print_stacktrace(void)
2002 #if defined(ENABLE_THREADS)
2004 java_lang_Thread *to;
2007 /* Get and clear exception because we are calling Java code
2010 e = exceptions_get_and_clear_exception();
2016 /* FIXME Enable me. */
2017 if (builtin_instanceof(e, class_java_lang_ThreadDeath)) {
2018 /* Don't print anything if we are being killed. */
2023 /* Get the exception class. */
2025 LLNI_class_get(e, c);
2027 /* Find the printStackTrace() method. */
2029 m = class_resolveclassmethod(c,
2030 utf_printStackTrace,
2032 class_java_lang_Object,
2036 vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
2038 /* Print message. */
2040 fprintf(stderr, "Exception ");
2042 #if defined(ENABLE_THREADS)
2043 /* Print thread name. We get the thread here explicitly as we
2044 need it afterwards. */
2046 t = thread_get_current();
2047 to = (java_lang_Thread *) thread_get_object(t);
2050 fprintf(stderr, "in thread \"");
2051 thread_fprint_name(t, stderr);
2052 fprintf(stderr, "\" ");
2056 /* Print the stacktrace. */
2058 if (builtin_instanceof(e, class_java_lang_Throwable)) {
2059 (void) vm_call_method(m, e);
2061 /* If this happens we are EXTREMLY out of memory or have a
2062 serious problem while printStackTrace. But may be
2063 another exception, so print it. */
2065 ne = exceptions_get_exception();
2068 fprintf(stderr, "Exception while printStackTrace(): ");
2070 /* Print the current exception. */
2072 exceptions_print_exception(ne);
2073 stacktrace_print_exception(ne);
2075 /* Now print the original exception. */
2077 fprintf(stderr, "Original exception was: ");
2078 exceptions_print_exception(e);
2079 stacktrace_print_exception(e);
2083 fprintf(stderr, ". Uncaught exception of type ");
2084 #if !defined(NDEBUG)
2085 /* FIXME This prints to stdout. */
2088 fprintf(stderr, "UNKNOWN");
2090 fprintf(stderr, ".");
2101 * These are local overrides for various environment variables in Emacs.
2102 * Please do not remove this and leave it at the end of the file, where
2103 * Emacs will automagically detect them.
2104 * ---------------------------------------------------------------------
2107 * indent-tabs-mode: t
2111 * vim:noexpandtab:sw=4:ts=4: