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.h"
51 #include "toolbox/util.h"
53 #include "vm/builtin.h"
54 #include "vm/exceptions.h"
55 #include "vm/global.h"
56 #include "vm/stringlocal.h"
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.h"
65 #include "vm/jit/trace.h"
67 #include "vmcore/class.h"
68 #include "vmcore/loader.h"
69 #include "vmcore/method.h"
70 #include "vmcore/options.h"
71 #include "vmcore/system.h"
73 #if defined(ENABLE_VMLOG)
74 #include <vmlog_cacao.h>
78 /* for raising exceptions from native methods *********************************/
80 #if !defined(ENABLE_THREADS)
81 java_object_t *_no_threads_exceptionptr = NULL;
85 /* exceptions_get_exception ****************************************************
87 Returns the current exception pointer of the current thread.
89 *******************************************************************************/
91 java_handle_t *exceptions_get_exception(void)
95 #if defined(ENABLE_THREADS)
101 /* Get the exception. */
105 #if defined(ENABLE_THREADS)
106 o = t->_exceptionptr;
108 o = _no_threads_exceptionptr;
115 /* Return the exception. */
121 /* exceptions_set_exception ****************************************************
123 Sets the exception pointer of the current thread.
125 *******************************************************************************/
127 void exceptions_set_exception(java_handle_t *e)
132 #if defined(ENABLE_THREADS)
138 /* Set the exception. */
145 if (opt_DebugExceptions) {
146 printf("[exceptions_set_exception : t=%p, o=%p, class=",
147 (void *) t, (void *) o);
148 class_print(o->vftbl->clazz);
153 #if defined(ENABLE_THREADS)
154 t->_exceptionptr = o;
156 _no_threads_exceptionptr = o;
163 /* exceptions_clear_exception **************************************************
165 Clears the current exception pointer of the current thread.
167 *******************************************************************************/
169 void exceptions_clear_exception(void)
173 #if defined(ENABLE_THREADS)
179 /* Set the exception. */
182 if (opt_DebugExceptions) {
183 printf("[exceptions_clear_exception: t=%p]\n", (void *) t);
187 #if defined(ENABLE_THREADS)
188 t->_exceptionptr = NULL;
190 _no_threads_exceptionptr = NULL;
195 /* exceptions_get_and_clear_exception ******************************************
197 Gets the exception pointer of the current thread and clears it.
198 This function may return NULL.
200 *******************************************************************************/
202 java_handle_t *exceptions_get_and_clear_exception(void)
206 /* Get the exception... */
208 o = exceptions_get_exception();
210 /* ...and clear the exception if it is set. */
213 exceptions_clear_exception();
215 /* return the exception */
221 /* exceptions_abort ************************************************************
223 Prints exception to be thrown and aborts.
226 classname....class name
227 message......exception message
229 *******************************************************************************/
231 static void exceptions_abort(utf *classname, utf *message)
233 log_println("exception thrown while VM is initializing: ");
236 utf_display_printable_ascii_classname(classname);
238 if (message != NULL) {
240 utf_display_printable_ascii_classname(message);
245 vm_abort("Aborting...");
249 /* exceptions_new_class_utf ****************************************************
251 Creates an exception object with the given class and initalizes it
252 with the given utf message.
255 c ......... exception class
256 message ... the message as an utf *
259 an exception pointer (in any case -- either it is the newly
260 created exception, or an exception thrown while trying to create
263 *******************************************************************************/
265 static java_handle_t *exceptions_new_class_utf(classinfo *c, utf *message)
270 if (vm_initializing) {
271 /* This can happen when global class variables are used which
272 are not initialized yet. */
275 exceptions_abort(NULL, message);
277 exceptions_abort(c->name, message);
280 s = javastring_new(message);
283 return exceptions_get_exception();
285 o = native_new_and_init_string(c, s);
288 return exceptions_get_exception();
294 /* exceptions_new_utf **********************************************************
296 Creates an exception object with the given name and initalizes it.
299 classname....class name in UTF-8
301 *******************************************************************************/
303 static java_handle_t *exceptions_new_utf(utf *classname)
309 exceptions_abort(classname, NULL);
311 c = load_class_bootstrap(classname);
314 return exceptions_get_exception();
316 o = native_new_and_init(c);
319 return exceptions_get_exception();
325 /* exceptions_new_utf_javastring ***********************************************
327 Creates an exception object with the given name and initalizes it
328 with the given java/lang/String message.
331 classname....class name in UTF-8
332 message......the message as a java.lang.String
335 an exception pointer (in any case -- either it is the newly created
336 exception, or an exception thrown while trying to create it).
338 *******************************************************************************/
340 static java_handle_t *exceptions_new_utf_javastring(utf *classname,
341 java_handle_t *message)
347 exceptions_abort(classname, NULL);
349 c = load_class_bootstrap(classname);
352 return exceptions_get_exception();
354 o = native_new_and_init_string(c, message);
357 return exceptions_get_exception();
363 /* exceptions_new_utf_utf ******************************************************
365 Creates an exception object with the given name and initalizes it
366 with the given utf message.
369 classname....class name in UTF-8
370 message......the message as an utf *
373 an exception pointer (in any case -- either it is the newly created
374 exception, or an exception thrown while trying to create it).
376 *******************************************************************************/
378 static java_handle_t *exceptions_new_utf_utf(utf *classname, utf *message)
384 exceptions_abort(classname, message);
386 c = load_class_bootstrap(classname);
389 return exceptions_get_exception();
391 o = exceptions_new_class_utf(c, message);
397 /* exceptions_throw_class_utf **************************************************
399 Creates an exception object with the given class, initalizes and
400 throws it with the given utf message.
403 c ......... exception class
404 message ... the message as an utf *
406 *******************************************************************************/
408 static void exceptions_throw_class_utf(classinfo *c, utf *message)
412 o = exceptions_new_class_utf(c, message);
414 exceptions_set_exception(o);
418 /* exceptions_throw_utf ********************************************************
420 Creates an exception object with the given name, initalizes and
424 classname....class name in UTF-8
426 *******************************************************************************/
428 static void exceptions_throw_utf(utf *classname)
432 o = exceptions_new_utf(classname);
437 exceptions_set_exception(o);
441 /* exceptions_throw_utf_throwable **********************************************
443 Creates an exception object with the given name and initalizes it
444 with the given java/lang/Throwable exception.
447 classname....class name in UTF-8
448 cause........the given Throwable
450 *******************************************************************************/
452 static void exceptions_throw_utf_throwable(utf *classname,
453 java_handle_t *cause)
458 java_lang_Throwable *object;
461 exceptions_abort(classname, NULL);
463 object = (java_lang_Throwable *) cause;
465 c = load_class_bootstrap(classname);
477 /* call initializer */
479 m = class_resolveclassmethod(c,
481 utf_java_lang_Throwable__void,
488 (void) vm_call_method(m, o, cause);
490 exceptions_set_exception(o);
494 /* exceptions_throw_utf_exception **********************************************
496 Creates an exception object with the given name and initalizes it
497 with the given java/lang/Exception exception.
500 classname....class name in UTF-8
501 exception....the given Exception
503 *******************************************************************************/
505 static void exceptions_throw_utf_exception(utf *classname,
506 java_handle_t *exception)
513 exceptions_abort(classname, NULL);
515 c = load_class_bootstrap(classname);
527 /* call initializer */
529 m = class_resolveclassmethod(c,
531 utf_java_lang_Exception__V,
538 (void) vm_call_method(m, o, exception);
540 exceptions_set_exception(o);
544 /* exceptions_throw_utf_cause **************************************************
546 Creates an exception object with the given name and initalizes it
547 with the given java/lang/Throwable exception with initCause.
550 classname....class name in UTF-8
551 cause........the given Throwable
553 *******************************************************************************/
555 static void exceptions_throw_utf_cause(utf *classname, java_handle_t *cause)
561 java_lang_Throwable *object;
564 exceptions_abort(classname, NULL);
566 object = (java_lang_Throwable *) cause;
568 c = load_class_bootstrap(classname);
580 /* call initializer */
582 m = class_resolveclassmethod(c,
584 utf_java_lang_String__void,
591 LLNI_field_get_ref(object, detailMessage, s);
593 (void) vm_call_method(m, o, s);
597 m = class_resolveclassmethod(c,
599 utf_java_lang_Throwable__java_lang_Throwable,
606 (void) vm_call_method(m, o, cause);
608 exceptions_set_exception(o);
612 /* exceptions_throw_utf_utf ****************************************************
614 Creates an exception object with the given name, initalizes and
615 throws it with the given utf message.
618 classname....class name in UTF-8
619 message......the message as an utf *
621 *******************************************************************************/
623 static void exceptions_throw_utf_utf(utf *classname, utf *message)
627 o = exceptions_new_utf_utf(classname, message);
629 exceptions_set_exception(o);
633 /* exceptions_new_abstractmethoderror ****************************************
635 Generates a java.lang.AbstractMethodError for the VM.
637 *******************************************************************************/
639 java_handle_t *exceptions_new_abstractmethoderror(void)
643 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
649 /* exceptions_new_error ********************************************************
651 Generates a java.lang.Error for the VM.
653 *******************************************************************************/
655 #if defined(ENABLE_JAVAME_CLDC1_1)
656 static java_handle_t *exceptions_new_error(utf *message)
660 o = exceptions_new_utf_utf(utf_java_lang_Error, message);
667 /* exceptions_asm_new_abstractmethoderror **************************************
669 Generates a java.lang.AbstractMethodError for
670 asm_abstractmethoderror.
672 *******************************************************************************/
674 java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
676 stackframeinfo_t sfi;
680 /* Fill and add a stackframeinfo (XPC is equal to RA). */
682 stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra);
684 /* create the exception */
686 #if defined(ENABLE_JAVASE)
687 e = exceptions_new_abstractmethoderror();
689 e = exceptions_new_error(utf_java_lang_AbstractMethodError);
692 /* Remove the stackframeinfo. */
694 stacktrace_stackframeinfo_remove(&sfi);
696 /* unwrap the exception */
697 /* ATTENTION: do the this _after_ the stackframeinfo was removed */
705 /* exceptions_new_arraystoreexception ******************************************
707 Generates a java.lang.ArrayStoreException for the VM.
709 *******************************************************************************/
711 java_handle_t *exceptions_new_arraystoreexception(void)
715 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
721 /* exceptions_throw_abstractmethoderror ****************************************
723 Generates and throws a java.lang.AbstractMethodError for the VM.
725 *******************************************************************************/
727 void exceptions_throw_abstractmethoderror(void)
729 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
733 /* exceptions_throw_classcircularityerror **************************************
735 Generates and throws a java.lang.ClassCircularityError for the
739 c....the class in which the error was found
741 *******************************************************************************/
743 void exceptions_throw_classcircularityerror(classinfo *c)
745 exceptions_throw_utf_utf(utf_java_lang_ClassCircularityError, c->name);
749 /* exceptions_throw_classformaterror *******************************************
751 Generates and throws a java.lang.ClassFormatError for the VM.
754 c............the class in which the error was found
755 message......UTF-8 format string
757 *******************************************************************************/
759 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
766 /* calculate message length */
771 msglen += utf_bytes(c->name) + strlen(" (");
773 va_start(ap, message);
774 msglen += get_variable_message_length(message, ap);
778 msglen += strlen(")");
780 msglen += strlen("0");
782 /* allocate a buffer */
784 msg = MNEW(char, msglen);
786 /* print message into allocated buffer */
789 utf_copy_classname(msg, c->name);
793 va_start(ap, message);
794 vsprintf(msg + strlen(msg), message, ap);
800 u = utf_new_char(msg);
804 MFREE(msg, char, msglen);
806 /* throw exception */
808 exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
812 /* exceptions_throw_classnotfoundexception *************************************
814 Generates and throws a java.lang.ClassNotFoundException for the
818 name.........name of the class not found as a utf *
820 *******************************************************************************/
822 void exceptions_throw_classnotfoundexception(utf *name)
824 exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
828 /* exceptions_throw_noclassdeffounderror ***************************************
830 Generates and throws a java.lang.NoClassDefFoundError.
833 name.........name of the class not found as a utf *
835 *******************************************************************************/
837 void exceptions_throw_noclassdeffounderror(utf *name)
839 exceptions_throw_utf_utf(utf_java_lang_NoClassDefFoundError, name);
843 /* exceptions_throw_noclassdeffounderror_cause *********************************
845 Generates and throws a java.lang.NoClassDefFoundError with the
848 *******************************************************************************/
850 void exceptions_throw_noclassdeffounderror_cause(java_handle_t *cause)
852 exceptions_throw_utf_cause(utf_java_lang_NoClassDefFoundError, cause);
856 /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
858 Generates and throws a java.lang.NoClassDefFoundError with a
862 name.........name of the class not found as a utf *
864 *******************************************************************************/
866 void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
872 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
873 utf_bytes(name) + strlen(")") + strlen("0");
875 msg = MNEW(char, msglen);
877 utf_copy_classname(msg, c->name);
878 strcat(msg, " (wrong name: ");
879 utf_cat_classname(msg, name);
882 u = utf_new_char(msg);
884 MFREE(msg, char, msglen);
886 exceptions_throw_noclassdeffounderror(u);
890 /* exceptions_throw_exceptionininitializererror ********************************
892 Generates and throws a java.lang.ExceptionInInitializerError for
896 cause......cause exception object
898 *******************************************************************************/
900 void exceptions_throw_exceptionininitializererror(java_handle_t *cause)
902 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
907 /* exceptions_throw_incompatibleclasschangeerror *******************************
909 Generates and throws a java.lang.IncompatibleClassChangeError for
913 message......UTF-8 message format string
915 *******************************************************************************/
917 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
923 /* calculate exception message length */
925 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
927 /* allocate memory */
929 msg = MNEW(char, msglen);
931 utf_copy_classname(msg, c->name);
932 strcat(msg, message);
934 u = utf_new_char(msg);
938 MFREE(msg, char, msglen);
940 /* throw exception */
942 exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
946 /* exceptions_throw_instantiationerror *****************************************
948 Generates and throws a java.lang.InstantiationError for the VM.
950 *******************************************************************************/
952 void exceptions_throw_instantiationerror(classinfo *c)
954 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
958 /* exceptions_throw_internalerror **********************************************
960 Generates and throws a java.lang.InternalError for the VM.
963 message......UTF-8 message format string
965 *******************************************************************************/
967 void exceptions_throw_internalerror(const char *message, ...)
974 /* calculate exception message length */
976 va_start(ap, message);
977 msglen = get_variable_message_length(message, ap);
980 /* allocate memory */
982 msg = MNEW(char, msglen);
984 /* generate message */
986 va_start(ap, message);
987 vsprintf(msg, message, ap);
990 u = utf_new_char(msg);
994 MFREE(msg, char, msglen);
996 /* throw exception */
998 exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
1002 /* exceptions_throw_linkageerror ***********************************************
1004 Generates and throws java.lang.LinkageError with an error message.
1007 message......UTF-8 message
1008 c............class related to the error. If this is != NULL
1009 the name of c is appended to the error message.
1011 *******************************************************************************/
1013 void exceptions_throw_linkageerror(const char *message, classinfo *c)
1019 /* calculate exception message length */
1021 len = strlen(message) + 1;
1024 len += utf_bytes(c->name);
1026 /* allocate memory */
1028 msg = MNEW(char, len);
1030 /* generate message */
1032 strcpy(msg, message);
1035 utf_cat_classname(msg, c->name);
1037 u = utf_new_char(msg);
1041 MFREE(msg, char, len);
1043 exceptions_throw_utf_utf(utf_java_lang_LinkageError, u);
1047 /* exceptions_throw_nosuchfielderror *******************************************
1049 Generates and throws a java.lang.NoSuchFieldError with an error
1053 c............class in which the field was not found
1054 name.........name of the field
1056 *******************************************************************************/
1058 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
1064 /* calculate exception message length */
1066 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
1068 /* allocate memory */
1070 msg = MNEW(char, msglen);
1072 /* generate message */
1074 utf_copy_classname(msg, c->name);
1078 u = utf_new_char(msg);
1082 MFREE(msg, char, msglen);
1084 exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
1088 /* exceptions_throw_nosuchmethoderror ******************************************
1090 Generates and throws a java.lang.NoSuchMethodError with an error
1094 c............class in which the method was not found
1095 name.........name of the method
1096 desc.........descriptor of the method
1098 *******************************************************************************/
1100 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
1106 /* calculate exception message length */
1108 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
1109 utf_bytes(desc) + strlen("0");
1111 /* allocate memory */
1113 msg = MNEW(char, msglen);
1115 /* generate message */
1117 utf_copy_classname(msg, c->name);
1122 u = utf_new_char(msg);
1126 MFREE(msg, char, msglen);
1128 #if defined(ENABLE_JAVASE)
1129 exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
1131 exceptions_throw_utf_utf(utf_java_lang_Error, u);
1136 /* exceptions_throw_outofmemoryerror *******************************************
1138 Generates and throws an java.lang.OutOfMemoryError for the VM.
1140 *******************************************************************************/
1142 void exceptions_throw_outofmemoryerror(void)
1144 exceptions_throw_utf(utf_java_lang_OutOfMemoryError);
1148 /* exceptions_throw_unsatisfiedlinkerror ***************************************
1150 Generates and throws a java.lang.UnsatisfiedLinkError for the
1154 name......UTF-8 name string
1156 *******************************************************************************/
1158 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1160 #if defined(ENABLE_JAVASE)
1161 exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1163 exceptions_throw_utf_utf(utf_java_lang_Error, name);
1168 /* exceptions_throw_unsupportedclassversionerror *******************************
1170 Generates and throws a java.lang.UnsupportedClassVersionError for
1174 c............class in which the method was not found
1175 message......UTF-8 format string
1177 *******************************************************************************/
1179 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1185 /* calculate exception message length */
1188 utf_bytes(c->name) +
1189 strlen(" (Unsupported major.minor version 00.0)") +
1192 /* allocate memory */
1194 msg = MNEW(char, msglen);
1196 /* generate message */
1198 utf_copy_classname(msg, c->name);
1199 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1202 u = utf_new_char(msg);
1206 MFREE(msg, char, msglen);
1208 /* throw exception */
1210 exceptions_throw_utf_utf(utf_java_lang_UnsupportedClassVersionError, u);
1214 /* exceptions_throw_verifyerror ************************************************
1216 Generates and throws a java.lang.VerifyError for the JIT compiler.
1219 m............method in which the error was found
1220 message......UTF-8 format string
1222 *******************************************************************************/
1224 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1231 /* calculate exception message length */
1237 strlen("(class: ") + utf_bytes(m->clazz->name) +
1238 strlen(", method: ") + utf_bytes(m->name) +
1239 strlen(" signature: ") + utf_bytes(m->descriptor) +
1240 strlen(") ") + strlen("0");
1242 va_start(ap, message);
1243 msglen += get_variable_message_length(message, ap);
1246 /* allocate memory */
1248 msg = MNEW(char, msglen);
1250 /* generate message */
1253 strcpy(msg, "(class: ");
1254 utf_cat_classname(msg, m->clazz->name);
1255 strcat(msg, ", method: ");
1256 utf_cat(msg, m->name);
1257 strcat(msg, " signature: ");
1258 utf_cat(msg, m->descriptor);
1262 va_start(ap, message);
1263 vsprintf(msg + strlen(msg), message, ap);
1266 u = utf_new_char(msg);
1270 MFREE(msg, char, msglen);
1272 /* throw exception */
1274 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1278 /* exceptions_throw_verifyerror_for_stack **************************************
1280 throws a java.lang.VerifyError for an invalid stack slot type
1283 m............method in which the error was found
1284 type.........the expected type
1287 an exception pointer (in any case -- either it is the newly created
1288 exception, or an exception thrown while trying to create it).
1290 *******************************************************************************/
1292 void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
1299 /* calculate exception message length */
1304 msglen = strlen("(class: ") + utf_bytes(m->clazz->name) +
1305 strlen(", method: ") + utf_bytes(m->name) +
1306 strlen(" signature: ") + utf_bytes(m->descriptor) +
1307 strlen(") Expecting to find longest-------typename on stack")
1310 /* allocate memory */
1312 msg = MNEW(char, msglen);
1314 /* generate message */
1317 strcpy(msg, "(class: ");
1318 utf_cat_classname(msg, m->clazz->name);
1319 strcat(msg, ", method: ");
1320 utf_cat(msg, m->name);
1321 strcat(msg, " signature: ");
1322 utf_cat(msg, m->descriptor);
1329 strcat(msg, "Expecting to find ");
1332 case TYPE_INT: typename = "integer"; break;
1333 case TYPE_LNG: typename = "long"; break;
1334 case TYPE_FLT: typename = "float"; break;
1335 case TYPE_DBL: typename = "double"; break;
1336 case TYPE_ADR: typename = "object/array"; break;
1337 case TYPE_RET: typename = "returnAddress"; break;
1338 default: typename = "<INVALID>"; assert(0); break;
1341 strcat(msg, typename);
1342 strcat(msg, " on stack");
1344 u = utf_new_char(msg);
1348 MFREE(msg, char, msglen);
1350 /* throw exception */
1352 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1356 /* exceptions_new_arithmeticexception ******************************************
1358 Generates a java.lang.ArithmeticException for the JIT compiler.
1360 *******************************************************************************/
1362 java_handle_t *exceptions_new_arithmeticexception(void)
1366 o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
1367 utf_division_by_zero);
1373 /* exceptions_new_arrayindexoutofboundsexception *******************************
1375 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1378 *******************************************************************************/
1380 java_handle_t *exceptions_new_arrayindexoutofboundsexception(s4 index)
1386 /* convert the index into a String, like Sun does */
1388 m = class_resolveclassmethod(class_java_lang_String,
1389 utf_new_char("valueOf"),
1390 utf_new_char("(I)Ljava/lang/String;"),
1391 class_java_lang_Object,
1395 return exceptions_get_exception();
1397 s = vm_call_method(m, NULL, index);
1400 return exceptions_get_exception();
1402 o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1406 return exceptions_get_exception();
1412 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1414 Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1417 *******************************************************************************/
1419 void exceptions_throw_arrayindexoutofboundsexception(void)
1421 exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1425 /* exceptions_throw_arraystoreexception ****************************************
1427 Generates and throws a java.lang.ArrayStoreException for the VM.
1429 *******************************************************************************/
1431 void exceptions_throw_arraystoreexception(void)
1433 exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1437 /* exceptions_new_classcastexception *******************************************
1439 Generates a java.lang.ClassCastException for the JIT compiler.
1441 *******************************************************************************/
1443 java_handle_t *exceptions_new_classcastexception(java_handle_t *o)
1449 LLNI_class_get(o, c);
1451 classname = c->name;
1453 e = exceptions_new_utf_utf(utf_java_lang_ClassCastException, classname);
1459 /* exceptions_throw_clonenotsupportedexception *********************************
1461 Generates and throws a java.lang.CloneNotSupportedException for the
1464 *******************************************************************************/
1466 void exceptions_throw_clonenotsupportedexception(void)
1468 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1472 /* exceptions_throw_illegalaccessexception *************************************
1474 Generates and throws a java.lang.IllegalAccessException for the VM.
1476 *******************************************************************************/
1478 void exceptions_throw_illegalaccessexception(utf *message)
1480 exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
1484 /* exceptions_throw_illegalargumentexception ***********************************
1486 Generates and throws a java.lang.IllegalArgumentException for the
1489 *******************************************************************************/
1491 void exceptions_throw_illegalargumentexception(void)
1493 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1497 /* exceptions_throw_illegalmonitorstateexception *******************************
1499 Generates and throws a java.lang.IllegalMonitorStateException for
1502 *******************************************************************************/
1504 void exceptions_throw_illegalmonitorstateexception(void)
1506 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1510 /* exceptions_throw_instantiationexception *************************************
1512 Generates and throws a java.lang.InstantiationException for the VM.
1514 *******************************************************************************/
1516 void exceptions_throw_instantiationexception(classinfo *c)
1518 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1522 /* exceptions_throw_interruptedexception ***************************************
1524 Generates and throws a java.lang.InterruptedException for the VM.
1526 *******************************************************************************/
1528 void exceptions_throw_interruptedexception(void)
1530 exceptions_throw_utf(utf_java_lang_InterruptedException);
1534 /* exceptions_throw_invocationtargetexception **********************************
1536 Generates and throws a java.lang.reflect.InvocationTargetException
1540 cause......cause exception object
1542 *******************************************************************************/
1544 void exceptions_throw_invocationtargetexception(java_handle_t *cause)
1546 exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1551 /* exceptions_throw_negativearraysizeexception *********************************
1553 Generates and throws a java.lang.NegativeArraySizeException for the
1556 *******************************************************************************/
1558 void exceptions_throw_negativearraysizeexception(void)
1560 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1564 /* exceptions_new_nullpointerexception *****************************************
1566 Generates a java.lang.NullPointerException for the VM system.
1568 *******************************************************************************/
1570 java_handle_t *exceptions_new_nullpointerexception(void)
1574 o = exceptions_new_utf(utf_java_lang_NullPointerException);
1580 /* exceptions_throw_nullpointerexception ***************************************
1582 Generates a java.lang.NullPointerException for the VM system and
1583 throw it in the VM system.
1585 *******************************************************************************/
1587 void exceptions_throw_nullpointerexception(void)
1589 exceptions_throw_utf(utf_java_lang_NullPointerException);
1593 /* exceptions_throw_privilegedactionexception **********************************
1595 Generates and throws a java.security.PrivilegedActionException.
1597 *******************************************************************************/
1599 void exceptions_throw_privilegedactionexception(java_handle_t *exception)
1601 exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
1606 /* exceptions_throw_stringindexoutofboundsexception ****************************
1608 Generates and throws a java.lang.StringIndexOutOfBoundsException
1611 *******************************************************************************/
1613 void exceptions_throw_stringindexoutofboundsexception(void)
1615 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1619 /* exceptions_fillinstacktrace *************************************************
1621 Calls the fillInStackTrace-method of the currently thrown
1624 *******************************************************************************/
1626 java_handle_t *exceptions_fillinstacktrace(void)
1634 o = exceptions_get_and_clear_exception();
1638 /* resolve methodinfo pointer from exception object */
1640 LLNI_class_get(o, c);
1642 #if defined(ENABLE_JAVASE)
1643 m = class_resolvemethod(c,
1644 utf_fillInStackTrace,
1645 utf_void__java_lang_Throwable);
1646 #elif defined(ENABLE_JAVAME_CLDC1_1)
1647 m = class_resolvemethod(c,
1648 utf_fillInStackTrace,
1651 #error IMPLEMENT ME!
1656 (void) vm_call_method(m, o);
1658 /* return exception object */
1664 /* exceptions_handle_exception *************************************************
1666 Try to find an exception handler for the given exception and return it.
1667 If no handler is found, exit the monitor of the method (if any)
1671 xptr.........the exception object
1672 xpc..........PC of where the exception was thrown
1673 pv...........Procedure Value of the current method
1674 sp...........current stack pointer
1677 the address of the first matching exception handler, or
1678 NULL if no handler was found
1680 *******************************************************************************/
1682 #if defined(ENABLE_JIT)
1683 void *exceptions_handle_exception(java_object_t *xptro, void *xpc, void *pv, void *sp)
1685 stackframeinfo_t sfi;
1686 java_handle_t *xptr;
1689 exceptiontable_t *et;
1690 exceptiontable_entry_t *ete;
1692 classref_or_classinfo cr;
1694 #if defined(ENABLE_THREADS)
1700 /* Addresses are 31 bit integers */
1701 # define ADDR_MASK(x) (void *) ((uintptr_t) (x) & 0x7FFFFFFF)
1703 # define ADDR_MASK(x) (x)
1706 xptr = LLNI_WRAP(xptro);
1707 xpc = ADDR_MASK(xpc);
1709 /* Fill and add a stackframeinfo (XPC is equal to RA). */
1711 stacktrace_stackframeinfo_add(&sfi, pv, sp, xpc, xpc);
1715 /* Get the codeinfo for the current method. */
1717 code = code_get_codeinfo_for_pv(pv);
1719 /* Get the methodinfo pointer from the codeinfo pointer. For
1720 asm_vm_call_method the codeinfo pointer is NULL and we simply
1721 can return the proper exception handler. */
1724 result = (void *) (uintptr_t) &asm_vm_call_method_exception_handler;
1725 goto exceptions_handle_exception_return;
1730 #if !defined(NDEBUG)
1731 /* print exception trace */
1733 if (opt_TraceExceptions)
1734 trace_exception(LLNI_DIRECT(xptr), m, xpc);
1736 # if defined(ENABLE_VMLOG)
1737 vmlog_cacao_throw(xptr);
1741 /* Get the exception table. */
1743 et = code->exceptiontable;
1746 /* Iterate over all exception table entries. */
1750 for (i = 0; i < et->length; i++, ete++) {
1751 /* is the xpc is the current catch range */
1753 if ((ADDR_MASK(ete->startpc) <= xpc) && (xpc < ADDR_MASK(ete->endpc))) {
1754 cr = ete->catchtype;
1756 /* NULL catches everything */
1758 if (cr.any == NULL) {
1759 #if !defined(NDEBUG)
1760 /* Print stacktrace of exception when caught. */
1762 # if defined(ENABLE_VMLOG)
1763 vmlog_cacao_catch(xptr);
1766 if (opt_TraceExceptions) {
1767 exceptions_print_exception(xptr);
1768 stacktrace_print_exception(xptr);
1772 result = ete->handlerpc;
1773 goto exceptions_handle_exception_return;
1776 /* resolve or load/link the exception class */
1778 if (IS_CLASSREF(cr)) {
1779 /* The exception class reference is unresolved. */
1780 /* We have to do _eager_ resolving here. While the
1781 class of the exception object is guaranteed to be
1782 loaded, it may well have been loaded by a different
1783 loader than the defining loader of m's class, which
1784 is the one we must use to resolve the catch
1785 class. Thus lazy resolving might fail, even if the
1786 result of the resolution would be an already loaded
1789 c = resolve_classref_eager(cr.ref);
1792 /* Exception resolving the exception class, argh! */
1793 goto exceptions_handle_exception_return;
1796 /* Ok, we resolved it. Enter it in the table, so we
1797 don't have to do this again. */
1798 /* XXX this write should be atomic. Is it? */
1800 ete->catchtype.cls = c;
1805 /* XXX I don't think this case can ever happen. -Edwin */
1806 if (!(c->state & CLASS_LOADED))
1807 /* use the methods' classloader */
1808 if (!load_class_from_classloader(c->name,
1809 m->clazz->classloader))
1810 goto exceptions_handle_exception_return;
1812 /* XXX I think, if it is not linked, we can be sure
1813 that the exception object is no (indirect) instance
1814 of it, no? -Edwin */
1815 if (!(c->state & CLASS_LINKED))
1817 goto exceptions_handle_exception_return;
1820 /* is the thrown exception an instance of the catch class? */
1822 if (builtin_instanceof(xptr, c)) {
1823 #if !defined(NDEBUG)
1824 /* Print stacktrace of exception when caught. */
1826 # if defined(ENABLE_VMLOG)
1827 vmlog_cacao_catch(xptr);
1830 if (opt_TraceExceptions) {
1831 exceptions_print_exception(xptr);
1832 stacktrace_print_exception(xptr);
1836 result = ete->handlerpc;
1837 goto exceptions_handle_exception_return;
1843 #if defined(ENABLE_THREADS)
1844 /* Is this method realization synchronized? */
1846 if (code_is_synchronized(code)) {
1847 /* Get synchronization object. */
1849 o = *((java_object_t **) (((uintptr_t) sp) + code->synchronizedoffset));
1853 lock_monitor_exit(LLNI_QUICKWRAP(o));
1857 /* none of the exceptions catch this one */
1859 #if !defined(NDEBUG)
1860 # if defined(ENABLE_VMLOG)
1861 vmlog_cacao_unwnd_method(m);
1864 # if defined(ENABLE_DEBUG_FILTER)
1865 if (show_filters_test_verbosecall_exit(m)) {
1868 /* outdent the log message */
1870 if (opt_verbosecall) {
1871 if (TRACEJAVACALLINDENT)
1872 TRACEJAVACALLINDENT--;
1874 log_text("exceptions_handle_exception: WARNING: unmatched unindent");
1877 # if defined(ENABLE_DEBUG_FILTER)
1880 #endif /* !defined(NDEBUG) */
1884 exceptions_handle_exception_return:
1886 /* Remove the stackframeinfo. */
1888 stacktrace_stackframeinfo_remove(&sfi);
1892 #endif /* defined(ENABLE_JIT) */
1895 /* exceptions_print_exception **************************************************
1897 Prints an exception, the detail message and the cause, if
1898 available, with CACAO internal functions to stdout.
1900 *******************************************************************************/
1902 void exceptions_print_exception(java_handle_t *xptr)
1904 java_lang_Throwable *t;
1905 #if defined(ENABLE_JAVASE)
1906 java_lang_Throwable *cause;
1908 java_lang_String *s;
1912 t = (java_lang_Throwable *) xptr;
1919 #if defined(ENABLE_JAVASE)
1920 LLNI_field_get_ref(t, cause, cause);
1923 /* print the root exception */
1925 LLNI_class_get(t, c);
1926 utf_display_printable_ascii_classname(c->name);
1928 LLNI_field_get_ref(t, detailMessage, s);
1931 u = javastring_toutf((java_handle_t *) s, false);
1934 utf_display_printable_ascii(u);
1939 #if defined(ENABLE_JAVASE)
1940 /* print the cause if available */
1942 if ((cause != NULL) && (cause != t)) {
1943 printf("Caused by: ");
1945 LLNI_class_get(cause, c);
1946 utf_display_printable_ascii_classname(c->name);
1948 LLNI_field_get_ref(cause, detailMessage, s);
1951 u = javastring_toutf((java_handle_t *) s, false);
1954 utf_display_printable_ascii(u);
1963 /* exceptions_print_current_exception ******************************************
1965 Prints the current pending exception, the detail message and the
1966 cause, if available, with CACAO internal functions to stdout.
1968 *******************************************************************************/
1970 void exceptions_print_current_exception(void)
1974 o = exceptions_get_exception();
1976 exceptions_print_exception(o);
1980 /* exceptions_print_stacktrace *************************************************
1982 Prints a pending exception with Throwable.printStackTrace(). If
1983 there happens an exception during printStackTrace(), we print the
1984 thrown exception and the original one.
1986 NOTE: This function calls Java code.
1988 *******************************************************************************/
1990 void exceptions_print_stacktrace(void)
1997 #if defined(ENABLE_THREADS)
1999 java_lang_Thread *to;
2002 /* Get and clear exception because we are calling Java code
2005 e = exceptions_get_and_clear_exception();
2011 /* FIXME Enable me. */
2012 if (builtin_instanceof(e, class_java_lang_ThreadDeath)) {
2013 /* Don't print anything if we are being killed. */
2018 /* Get the exception class. */
2020 LLNI_class_get(e, c);
2022 /* Find the printStackTrace() method. */
2024 m = class_resolveclassmethod(c,
2025 utf_printStackTrace,
2027 class_java_lang_Object,
2031 vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
2033 /* Print message. */
2035 fprintf(stderr, "Exception ");
2037 #if defined(ENABLE_THREADS)
2038 /* Print thread name. We get the thread here explicitly as we
2039 need it afterwards. */
2041 t = thread_get_current();
2042 to = (java_lang_Thread *) thread_get_object(t);
2045 fprintf(stderr, "in thread \"");
2046 thread_fprint_name(t, stderr);
2047 fprintf(stderr, "\" ");
2051 /* Print the stacktrace. */
2053 if (builtin_instanceof(e, class_java_lang_Throwable)) {
2054 (void) vm_call_method(m, e);
2056 /* If this happens we are EXTREMLY out of memory or have a
2057 serious problem while printStackTrace. But may be
2058 another exception, so print it. */
2060 ne = exceptions_get_exception();
2063 fprintf(stderr, "Exception while printStackTrace(): ");
2065 /* Print the current exception. */
2067 exceptions_print_exception(ne);
2068 stacktrace_print_exception(ne);
2070 /* Now print the original exception. */
2072 fprintf(stderr, "Original exception was: ");
2073 exceptions_print_exception(e);
2074 stacktrace_print_exception(e);
2078 fprintf(stderr, ". Uncaught exception of type ");
2079 #if !defined(NDEBUG)
2080 /* FIXME This prints to stdout. */
2083 fprintf(stderr, "UNKNOWN");
2085 fprintf(stderr, ".");
2094 * These are local overrides for various environment variables in Emacs.
2095 * Please do not remove this and leave it at the end of the file, where
2096 * Emacs will automagically detect them.
2097 * ---------------------------------------------------------------------
2100 * indent-tabs-mode: t
2104 * vim:noexpandtab:sw=4:ts=4: