1 /* src/vm/exceptions.cpp - exception related functions
3 Copyright (C) 1996-2011
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
37 #include "mm/memory.hpp"
39 #include "native/llni.h"
40 #include "native/native.hpp"
42 #include "threads/lock.hpp"
43 #include "threads/thread.hpp"
45 #include "toolbox/util.h"
47 #include "vm/jit/builtin.hpp"
48 #include "vm/class.hpp"
49 #include "vm/exceptions.hpp"
50 #include "vm/global.h"
51 #include "vm/globals.hpp"
52 #include "vm/javaobjects.hpp"
53 #include "vm/loader.hpp"
54 #include "vm/method.hpp"
55 #include "vm/options.h"
57 #include "vm/string.hpp"
60 #include "vm/jit/asmpart.h"
61 #include "vm/jit/jit.hpp"
62 #include "vm/jit/methodheader.h"
63 #include "vm/jit/patcher-common.hpp"
64 #include "vm/jit/show.hpp"
65 #include "vm/jit/stacktrace.hpp"
66 #include "vm/jit/trace.hpp"
68 #if defined(ENABLE_VMLOG)
69 #include <vmlog_cacao.h>
76 /* for raising exceptions from native methods *********************************/
78 #if !defined(ENABLE_THREADS)
79 java_object_t *_no_threads_exceptionptr = NULL;
83 /* exceptions_get_exception ****************************************************
85 Returns the current exception pointer of the current thread.
87 *******************************************************************************/
89 java_handle_t *exceptions_get_exception(void)
93 #if defined(ENABLE_THREADS)
99 /* Get the exception. */
103 #if defined(ENABLE_THREADS)
104 o = t->_exceptionptr;
106 o = _no_threads_exceptionptr;
113 /* Return the exception. */
119 /* exceptions_set_exception ****************************************************
121 Sets the exception pointer of the current thread.
123 *******************************************************************************/
125 void exceptions_set_exception(java_handle_t *e)
130 #if defined(ENABLE_THREADS)
136 /* Set the exception. */
143 if (opt_DebugExceptions) {
144 printf("[exceptions_set_exception : t=%p, o=%p, class=",
145 (void *) t, (void *) o);
146 class_print(o->vftbl->clazz);
151 #if defined(ENABLE_THREADS)
152 t->_exceptionptr = o;
154 _no_threads_exceptionptr = o;
161 /* exceptions_clear_exception **************************************************
163 Clears the current exception pointer of the current thread.
165 *******************************************************************************/
167 void exceptions_clear_exception(void)
171 #if defined(ENABLE_THREADS)
177 /* Set the exception. */
180 if (opt_DebugExceptions) {
181 printf("[exceptions_clear_exception: t=%p]\n", (void *) t);
185 #if defined(ENABLE_THREADS)
186 t->_exceptionptr = NULL;
188 _no_threads_exceptionptr = NULL;
193 /* exceptions_get_and_clear_exception ******************************************
195 Gets the exception pointer of the current thread and clears it.
196 This function may return NULL.
198 *******************************************************************************/
200 java_handle_t *exceptions_get_and_clear_exception(void)
204 /* Get the exception... */
206 o = exceptions_get_exception();
208 /* ...and clear the exception if it is set. */
211 exceptions_clear_exception();
213 /* return the exception */
219 /* exceptions_abort ************************************************************
221 Prints exception to be thrown and aborts.
224 classname....class name
225 message......exception message
227 *******************************************************************************/
229 static void exceptions_abort(utf *classname, utf *message)
231 log_println("exception thrown while VM is initializing: ");
234 utf_display_printable_ascii_classname(classname);
236 if (message != NULL) {
238 utf_display_printable_ascii_classname(message);
243 os::abort("Aborting...");
247 /* exceptions_new_class_utf ****************************************************
249 Creates an exception object with the given class and initalizes it
250 with the given utf message.
253 c ......... exception class
254 message ... the message as an utf *
257 an exception pointer (in any case -- either it is the newly
258 created exception, or an exception thrown while trying to create
261 *******************************************************************************/
263 static java_handle_t *exceptions_new_class_utf(classinfo *c, utf *message)
268 if (VM::get_current()->is_initializing()) {
269 /* This can happen when global class variables are used which
270 are not initialized yet. */
273 exceptions_abort(NULL, message);
275 exceptions_abort(c->name, message);
278 s = javastring_new(message);
281 return exceptions_get_exception();
283 o = native_new_and_init_string(c, s);
286 return exceptions_get_exception();
292 /* exceptions_new_utf **********************************************************
294 Creates an exception object with the given name and initalizes it.
297 classname....class name in UTF-8
299 *******************************************************************************/
301 static java_handle_t *exceptions_new_utf(utf *classname)
306 if (VM::get_current()->is_initializing())
307 exceptions_abort(classname, NULL);
309 c = load_class_bootstrap(classname);
312 return exceptions_get_exception();
314 o = native_new_and_init(c);
317 return exceptions_get_exception();
323 /* exceptions_new_utf_javastring ***********************************************
325 Creates an exception object with the given name and initalizes it
326 with the given java/lang/String message.
329 classname....class name in UTF-8
330 message......the message as a java.lang.String
333 an exception pointer (in any case -- either it is the newly created
334 exception, or an exception thrown while trying to create it).
336 *******************************************************************************/
338 static java_handle_t *exceptions_new_utf_javastring(utf *classname,
339 java_handle_t *message)
344 if (VM::get_current()->is_initializing())
345 exceptions_abort(classname, NULL);
347 c = load_class_bootstrap(classname);
350 return exceptions_get_exception();
352 o = native_new_and_init_string(c, message);
355 return exceptions_get_exception();
361 /* exceptions_new_utf_utf ******************************************************
363 Creates an exception object with the given name and initalizes it
364 with the given utf message.
367 classname....class name in UTF-8
368 message......the message as an utf *
371 an exception pointer (in any case -- either it is the newly created
372 exception, or an exception thrown while trying to create it).
374 *******************************************************************************/
376 static java_handle_t *exceptions_new_utf_utf(utf *classname, utf *message)
381 if (VM::get_current()->is_initializing())
382 exceptions_abort(classname, message);
384 c = load_class_bootstrap(classname);
387 return exceptions_get_exception();
389 o = exceptions_new_class_utf(c, message);
395 /* exceptions_throw_class_utf **************************************************
397 Creates an exception object with the given class, initalizes and
398 throws it with the given utf message.
401 c ......... exception class
402 message ... the message as an utf *
404 *******************************************************************************/
406 static void exceptions_throw_class_utf(classinfo *c, utf *message)
410 o = exceptions_new_class_utf(c, message);
412 exceptions_set_exception(o);
416 /* exceptions_throw_utf ********************************************************
418 Creates an exception object with the given name, initalizes and
422 classname....class name in UTF-8
424 *******************************************************************************/
426 static void exceptions_throw_utf(utf *classname)
430 o = exceptions_new_utf(classname);
435 exceptions_set_exception(o);
439 /* exceptions_throw_utf_throwable **********************************************
441 Creates an exception object with the given name and initalizes it
442 with the given java/lang/Throwable exception.
445 classname....class name in UTF-8
446 cause........the given Throwable
448 *******************************************************************************/
450 static void exceptions_throw_utf_throwable(utf *classname,
451 java_handle_t *cause)
456 if (VM::get_current()->is_initializing())
457 exceptions_abort(classname, NULL);
459 java_lang_Throwable jlt(cause);
461 c = load_class_bootstrap(classname);
468 java_handle_t* h = builtin_new(c);
473 /* call initializer */
475 m = class_resolveclassmethod(c,
477 utf_java_lang_Throwable__void,
484 (void) vm_call_method(m, h, jlt.get_handle());
486 exceptions_set_exception(h);
490 /* exceptions_throw_utf_exception **********************************************
492 Creates an exception object with the given name and initalizes it
493 with the given java/lang/Exception exception.
496 classname....class name in UTF-8
497 exception....the given Exception
499 *******************************************************************************/
501 static void exceptions_throw_utf_exception(utf *classname,
502 java_handle_t *exception)
508 if (VM::get_current()->is_initializing())
509 exceptions_abort(classname, NULL);
511 c = load_class_bootstrap(classname);
523 /* call initializer */
525 m = class_resolveclassmethod(c,
527 utf_java_lang_Exception__V,
534 (void) vm_call_method(m, o, exception);
536 exceptions_set_exception(o);
540 /* exceptions_throw_utf_cause **************************************************
542 Creates an exception object with the given name and initalizes it
543 with the given java/lang/Throwable exception with initCause.
546 classname....class name in UTF-8
547 cause........the given Throwable
549 *******************************************************************************/
551 static void exceptions_throw_utf_cause(utf *classname, java_handle_t *cause)
553 if (VM::get_current()->is_initializing())
554 exceptions_abort(classname, NULL);
556 java_lang_Throwable jltcause(cause);
558 classinfo* c = load_class_bootstrap(classname);
565 java_handle_t* h = builtin_new(c);
570 /* call initializer */
572 methodinfo* m = class_resolveclassmethod(c,
574 utf_java_lang_String__void,
581 (void) vm_call_method(m, h, jltcause.get_detailMessage());
585 m = class_resolveclassmethod(c,
587 utf_java_lang_Throwable__java_lang_Throwable,
594 (void) vm_call_method(m, h, jltcause.get_handle());
596 exceptions_set_exception(h);
600 /* exceptions_throw_utf_utf ****************************************************
602 Creates an exception object with the given name, initalizes and
603 throws it with the given utf message.
606 classname....class name in UTF-8
607 message......the message as an utf *
609 *******************************************************************************/
611 static void exceptions_throw_utf_utf(utf *classname, utf *message)
615 o = exceptions_new_utf_utf(classname, message);
617 exceptions_set_exception(o);
621 /* exceptions_new_abstractmethoderror ****************************************
623 Generates a java.lang.AbstractMethodError for the VM.
625 *******************************************************************************/
627 java_handle_t *exceptions_new_abstractmethoderror(void)
631 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
637 /* exceptions_new_error ********************************************************
639 Generates a java.lang.Error for the VM.
641 *******************************************************************************/
643 #if defined(ENABLE_JAVAME_CLDC1_1)
644 static java_handle_t *exceptions_new_error(utf *message)
648 o = exceptions_new_utf_utf(utf_java_lang_Error, message);
655 /* exceptions_asm_new_abstractmethoderror **************************************
657 Generates a java.lang.AbstractMethodError for
658 asm_abstractmethoderror.
660 *******************************************************************************/
662 java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
664 stackframeinfo_t sfi;
668 /* Fill and add a stackframeinfo (XPC is equal to RA). */
670 stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra);
672 /* create the exception */
674 #if defined(ENABLE_JAVASE)
675 e = exceptions_new_abstractmethoderror();
677 e = exceptions_new_error(utf_java_lang_AbstractMethodError);
680 /* Remove the stackframeinfo. */
682 stacktrace_stackframeinfo_remove(&sfi);
684 /* unwrap the exception */
685 /* ATTENTION: do the this _after_ the stackframeinfo was removed */
693 /* exceptions_new_arraystoreexception ******************************************
695 Generates a java.lang.ArrayStoreException for the VM.
697 *******************************************************************************/
699 java_handle_t *exceptions_new_arraystoreexception(void)
703 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
709 /* exceptions_throw_abstractmethoderror ****************************************
711 Generates and throws a java.lang.AbstractMethodError for the VM.
713 *******************************************************************************/
715 void exceptions_throw_abstractmethoderror(void)
717 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
721 /* exceptions_throw_classcircularityerror **************************************
723 Generates and throws a java.lang.ClassCircularityError for the
727 c....the class in which the error was found
729 *******************************************************************************/
731 void exceptions_throw_classcircularityerror(classinfo *c)
733 exceptions_throw_utf_utf(utf_java_lang_ClassCircularityError, c->name);
737 /* exceptions_throw_classformaterror *******************************************
739 Generates and throws a java.lang.ClassFormatError for the VM.
742 c............the class in which the error was found
743 message......UTF-8 format string
745 *******************************************************************************/
747 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
754 /* calculate message length */
759 msglen += utf_bytes(c->name) + strlen(" (");
761 va_start(ap, message);
762 msglen += get_variable_message_length(message, ap);
766 msglen += strlen(")");
768 msglen += strlen("0");
770 /* allocate a buffer */
772 msg = MNEW(char, msglen);
774 /* print message into allocated buffer */
777 utf_copy_classname(msg, c->name);
781 va_start(ap, message);
782 vsprintf(msg + strlen(msg), message, ap);
788 u = utf_new_char(msg);
792 MFREE(msg, char, msglen);
794 /* throw exception */
796 exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
800 /* exceptions_throw_classnotfoundexception *************************************
802 Generates and throws a java.lang.ClassNotFoundException for the
806 name.........name of the class not found as a utf *
808 *******************************************************************************/
810 void exceptions_throw_classnotfoundexception(utf *name)
812 exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
816 /* exceptions_throw_noclassdeffounderror ***************************************
818 Generates and throws a java.lang.NoClassDefFoundError.
821 name.........name of the class not found as a utf *
823 *******************************************************************************/
825 void exceptions_throw_noclassdeffounderror(utf *name)
827 exceptions_throw_utf_utf(utf_java_lang_NoClassDefFoundError, name);
831 /* exceptions_throw_noclassdeffounderror_cause *********************************
833 Generates and throws a java.lang.NoClassDefFoundError with the
836 *******************************************************************************/
838 void exceptions_throw_noclassdeffounderror_cause(java_handle_t *cause)
840 exceptions_throw_utf_cause(utf_java_lang_NoClassDefFoundError, cause);
844 /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
846 Generates and throws a java.lang.NoClassDefFoundError with a
850 name.........name of the class not found as a utf *
852 *******************************************************************************/
854 void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
860 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
861 utf_bytes(name) + strlen(")") + strlen("0");
863 msg = MNEW(char, msglen);
865 utf_copy_classname(msg, c->name);
866 strcat(msg, " (wrong name: ");
867 utf_cat_classname(msg, name);
870 u = utf_new_char(msg);
872 MFREE(msg, char, msglen);
874 exceptions_throw_noclassdeffounderror(u);
878 /* exceptions_throw_exceptionininitializererror ********************************
880 Generates and throws a java.lang.ExceptionInInitializerError for
884 cause......cause exception object
886 *******************************************************************************/
888 void exceptions_throw_exceptionininitializererror(java_handle_t *cause)
890 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
895 /* exceptions_throw_incompatibleclasschangeerror *******************************
897 Generates and throws a java.lang.IncompatibleClassChangeError for
901 message......UTF-8 message format string
903 *******************************************************************************/
905 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
911 /* calculate exception message length */
913 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
915 /* allocate memory */
917 msg = MNEW(char, msglen);
919 utf_copy_classname(msg, c->name);
920 strcat(msg, message);
922 u = utf_new_char(msg);
926 MFREE(msg, char, msglen);
928 /* throw exception */
930 exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
934 /* exceptions_throw_instantiationerror *****************************************
936 Generates and throws a java.lang.InstantiationError for the VM.
938 *******************************************************************************/
940 void exceptions_throw_instantiationerror(classinfo *c)
942 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
946 /* exceptions_throw_internalerror **********************************************
948 Generates and throws a java.lang.InternalError for the VM.
951 message......UTF-8 message format string
953 *******************************************************************************/
955 void exceptions_throw_internalerror(const char *message, ...)
962 /* calculate exception message length */
964 va_start(ap, message);
965 msglen = get_variable_message_length(message, ap);
968 /* allocate memory */
970 msg = MNEW(char, msglen);
972 /* generate message */
974 va_start(ap, message);
975 vsprintf(msg, message, ap);
978 u = utf_new_char(msg);
982 MFREE(msg, char, msglen);
984 /* throw exception */
986 exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
990 /* exceptions_throw_linkageerror ***********************************************
992 Generates and throws java.lang.LinkageError with an error message.
995 message......UTF-8 message
996 c............class related to the error. If this is != NULL
997 the name of c is appended to the error message.
999 *******************************************************************************/
1001 void exceptions_throw_linkageerror(const char *message, classinfo *c)
1007 /* calculate exception message length */
1009 len = strlen(message) + 1;
1012 len += utf_bytes(c->name);
1014 /* allocate memory */
1016 msg = MNEW(char, len);
1018 /* generate message */
1020 strcpy(msg, message);
1023 utf_cat_classname(msg, c->name);
1025 u = utf_new_char(msg);
1029 MFREE(msg, char, len);
1031 exceptions_throw_utf_utf(utf_java_lang_LinkageError, u);
1035 /* exceptions_throw_nosuchfielderror *******************************************
1037 Generates and throws a java.lang.NoSuchFieldError with an error
1041 c............class in which the field was not found
1042 name.........name of the field
1044 *******************************************************************************/
1046 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
1052 /* calculate exception message length */
1054 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
1056 /* allocate memory */
1058 msg = MNEW(char, msglen);
1060 /* generate message */
1062 utf_copy_classname(msg, c->name);
1066 u = utf_new_char(msg);
1070 MFREE(msg, char, msglen);
1072 exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
1076 /* exceptions_throw_nosuchmethoderror ******************************************
1078 Generates and throws a java.lang.NoSuchMethodError with an error
1082 c............class in which the method was not found
1083 name.........name of the method
1084 desc.........descriptor of the method
1086 *******************************************************************************/
1088 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
1094 /* calculate exception message length */
1096 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
1097 utf_bytes(desc) + strlen("0");
1099 /* allocate memory */
1101 msg = MNEW(char, msglen);
1103 /* generate message */
1105 utf_copy_classname(msg, c->name);
1110 u = utf_new_char(msg);
1114 MFREE(msg, char, msglen);
1116 #if defined(ENABLE_JAVASE)
1117 exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
1119 exceptions_throw_utf_utf(utf_java_lang_Error, u);
1124 /* exceptions_throw_outofmemoryerror *******************************************
1126 Generates and throws an java.lang.OutOfMemoryError for the VM.
1128 *******************************************************************************/
1130 void exceptions_throw_outofmemoryerror(void)
1132 exceptions_throw_utf(utf_java_lang_OutOfMemoryError);
1136 /* exceptions_throw_unsatisfiedlinkerror ***************************************
1138 Generates and throws a java.lang.UnsatisfiedLinkError for the
1142 name......UTF-8 name string
1144 *******************************************************************************/
1146 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1148 #if defined(ENABLE_JAVASE)
1149 exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1151 exceptions_throw_utf_utf(utf_java_lang_Error, name);
1156 /* exceptions_throw_unsupportedclassversionerror *******************************
1158 Generates and throws a java.lang.UnsupportedClassVersionError for
1162 c............class in which the method was not found
1163 message......UTF-8 format string
1165 *******************************************************************************/
1167 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1173 /* calculate exception message length */
1176 utf_bytes(c->name) +
1177 strlen(" (Unsupported major.minor version 00.0)") +
1180 /* allocate memory */
1182 msg = MNEW(char, msglen);
1184 /* generate message */
1186 utf_copy_classname(msg, c->name);
1187 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1190 u = utf_new_char(msg);
1194 MFREE(msg, char, msglen);
1196 /* throw exception */
1198 exceptions_throw_utf_utf(utf_java_lang_UnsupportedClassVersionError, u);
1202 /* exceptions_throw_verifyerror ************************************************
1204 Generates and throws a java.lang.VerifyError for the JIT compiler.
1207 m............method in which the error was found
1208 message......UTF-8 format string
1210 *******************************************************************************/
1212 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1219 /* calculate exception message length */
1225 strlen("(class: ") + utf_bytes(m->clazz->name) +
1226 strlen(", method: ") + utf_bytes(m->name) +
1227 strlen(" signature: ") + utf_bytes(m->descriptor) +
1228 strlen(") ") + strlen("0");
1230 va_start(ap, message);
1231 msglen += get_variable_message_length(message, ap);
1234 /* allocate memory */
1236 msg = MNEW(char, msglen);
1238 /* generate message */
1241 strcpy(msg, "(class: ");
1242 utf_cat_classname(msg, m->clazz->name);
1243 strcat(msg, ", method: ");
1244 utf_cat(msg, m->name);
1245 strcat(msg, " signature: ");
1246 utf_cat(msg, m->descriptor);
1250 va_start(ap, message);
1251 vsprintf(msg + strlen(msg), message, ap);
1254 u = utf_new_char(msg);
1258 MFREE(msg, char, msglen);
1260 /* throw exception */
1262 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1266 /* exceptions_throw_verifyerror_for_stack **************************************
1268 throws a java.lang.VerifyError for an invalid stack slot type
1271 m............method in which the error was found
1272 type.........the expected type
1275 an exception pointer (in any case -- either it is the newly created
1276 exception, or an exception thrown while trying to create it).
1278 *******************************************************************************/
1280 void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
1286 /* calculate exception message length */
1291 msglen = strlen("(class: ") + utf_bytes(m->clazz->name) +
1292 strlen(", method: ") + utf_bytes(m->name) +
1293 strlen(" signature: ") + utf_bytes(m->descriptor) +
1294 strlen(") Expecting to find longest-------typename on stack")
1297 /* allocate memory */
1299 msg = MNEW(char, msglen);
1301 /* generate message */
1304 strcpy(msg, "(class: ");
1305 utf_cat_classname(msg, m->clazz->name);
1306 strcat(msg, ", method: ");
1307 utf_cat(msg, m->name);
1308 strcat(msg, " signature: ");
1309 utf_cat(msg, m->descriptor);
1316 strcat(msg, "Expecting to find ");
1321 case TYPE_INT: name = "integer"; break;
1322 case TYPE_LNG: name = "long"; break;
1323 case TYPE_FLT: name = "float"; break;
1324 case TYPE_DBL: name = "double"; break;
1325 case TYPE_ADR: name = "object/array"; break;
1326 case TYPE_RET: name = "returnAddress"; break;
1327 default: name = "<INVALID>"; assert(0); break;
1331 strcat(msg, " on stack");
1333 u = utf_new_char(msg);
1337 MFREE(msg, char, msglen);
1339 /* throw exception */
1341 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1345 /* exceptions_new_arithmeticexception ******************************************
1347 Generates a java.lang.ArithmeticException for the JIT compiler.
1349 *******************************************************************************/
1351 java_handle_t *exceptions_new_arithmeticexception(void)
1355 o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
1356 utf_division_by_zero);
1362 /* exceptions_new_arrayindexoutofboundsexception *******************************
1364 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1367 *******************************************************************************/
1369 java_handle_t *exceptions_new_arrayindexoutofboundsexception(s4 index)
1375 /* convert the index into a String, like Sun does */
1377 m = class_resolveclassmethod(class_java_lang_String,
1378 utf_new_char("valueOf"),
1379 utf_new_char("(I)Ljava/lang/String;"),
1380 class_java_lang_Object,
1384 return exceptions_get_exception();
1386 s = vm_call_method(m, NULL, index);
1389 return exceptions_get_exception();
1391 o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1395 return exceptions_get_exception();
1401 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1403 Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1406 *******************************************************************************/
1408 void exceptions_throw_arrayindexoutofboundsexception(void)
1410 exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1414 /* exceptions_throw_arraystoreexception ****************************************
1416 Generates and throws a java.lang.ArrayStoreException for the VM.
1418 *******************************************************************************/
1420 void exceptions_throw_arraystoreexception(void)
1422 exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1426 /* exceptions_new_classcastexception *******************************************
1428 Generates a java.lang.ClassCastException for the JIT compiler.
1430 *******************************************************************************/
1432 java_handle_t *exceptions_new_classcastexception(java_handle_t *o)
1438 LLNI_class_get(o, c);
1440 classname = c->name;
1442 e = exceptions_new_utf_utf(utf_java_lang_ClassCastException, classname);
1448 /* exceptions_throw_clonenotsupportedexception *********************************
1450 Generates and throws a java.lang.CloneNotSupportedException for the
1453 *******************************************************************************/
1455 void exceptions_throw_clonenotsupportedexception(void)
1457 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1461 /* exceptions_throw_illegalaccessexception *************************************
1463 Generates and throws a java.lang.IllegalAccessException for the VM.
1465 *******************************************************************************/
1467 void exceptions_throw_illegalaccessexception(utf *message)
1469 exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
1473 /* exceptions_throw_illegalargumentexception ***********************************
1475 Generates and throws a java.lang.IllegalArgumentException for the
1478 *******************************************************************************/
1480 void exceptions_throw_illegalargumentexception(void)
1482 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1486 /* exceptions_throw_illegalmonitorstateexception *******************************
1488 Generates and throws a java.lang.IllegalMonitorStateException for
1491 *******************************************************************************/
1493 void exceptions_throw_illegalmonitorstateexception(void)
1495 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1499 /* exceptions_throw_instantiationexception *************************************
1501 Generates and throws a java.lang.InstantiationException for the VM.
1503 *******************************************************************************/
1505 void exceptions_throw_instantiationexception(classinfo *c)
1507 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1511 /* exceptions_throw_interruptedexception ***************************************
1513 Generates and throws a java.lang.InterruptedException for the VM.
1515 *******************************************************************************/
1517 void exceptions_throw_interruptedexception(void)
1519 exceptions_throw_utf(utf_java_lang_InterruptedException);
1523 /* exceptions_throw_invocationtargetexception **********************************
1525 Generates and throws a java.lang.reflect.InvocationTargetException
1529 cause......cause exception object
1531 *******************************************************************************/
1533 void exceptions_throw_invocationtargetexception(java_handle_t *cause)
1535 exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1540 /* exceptions_throw_negativearraysizeexception *********************************
1542 Generates and throws a java.lang.NegativeArraySizeException for the
1545 *******************************************************************************/
1547 void exceptions_throw_negativearraysizeexception(void)
1549 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1553 /* exceptions_new_nullpointerexception *****************************************
1555 Generates a java.lang.NullPointerException for the VM system.
1557 *******************************************************************************/
1559 java_handle_t *exceptions_new_nullpointerexception(void)
1563 o = exceptions_new_utf(utf_java_lang_NullPointerException);
1569 /* exceptions_throw_nullpointerexception ***************************************
1571 Generates a java.lang.NullPointerException for the VM system and
1572 throw it in the VM system.
1574 *******************************************************************************/
1576 void exceptions_throw_nullpointerexception(void)
1578 exceptions_throw_utf(utf_java_lang_NullPointerException);
1582 /* exceptions_throw_privilegedactionexception **********************************
1584 Generates and throws a java.security.PrivilegedActionException.
1586 *******************************************************************************/
1588 void exceptions_throw_privilegedactionexception(java_handle_t *exception)
1590 exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
1595 /* exceptions_throw_stringindexoutofboundsexception ****************************
1597 Generates and throws a java.lang.StringIndexOutOfBoundsException
1600 *******************************************************************************/
1602 void exceptions_throw_stringindexoutofboundsexception(void)
1604 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1608 /* exceptions_fillinstacktrace *************************************************
1610 Calls the fillInStackTrace-method of the currently thrown
1613 *******************************************************************************/
1615 java_handle_t *exceptions_fillinstacktrace(void)
1623 o = exceptions_get_and_clear_exception();
1627 /* resolve methodinfo pointer from exception object */
1629 LLNI_class_get(o, c);
1631 #if defined(ENABLE_JAVASE)
1632 m = class_resolvemethod(c,
1633 utf_fillInStackTrace,
1634 utf_void__java_lang_Throwable);
1635 #elif defined(ENABLE_JAVAME_CLDC1_1)
1636 m = class_resolvemethod(c,
1637 utf_fillInStackTrace,
1640 #error IMPLEMENT ME!
1645 (void) vm_call_method(m, o);
1647 /* return exception object */
1653 /* exceptions_handle_exception *************************************************
1655 Try to find an exception handler for the given exception and return it.
1656 If no handler is found, exit the monitor of the method (if any)
1660 xptr.........the exception object
1661 xpc..........PC of where the exception was thrown
1662 pv...........Procedure Value of the current method
1663 sp...........current stack pointer
1666 the address of the first matching exception handler, or
1667 NULL if no handler was found
1669 *******************************************************************************/
1671 #if defined(ENABLE_JIT)
1672 void *exceptions_handle_exception(java_object_t *xptro, void *xpc, void *pv, void *sp)
1674 stackframeinfo_t sfi;
1675 java_handle_t *xptr;
1678 exceptiontable_t *et;
1679 exceptiontable_entry_t *ete;
1681 classref_or_classinfo cr;
1683 #if defined(ENABLE_THREADS)
1689 /* Addresses are 31 bit integers */
1690 # define ADDR_MASK(x) (void *) ((uintptr_t) (x) & 0x7FFFFFFF)
1692 # define ADDR_MASK(x) (x)
1695 xptr = LLNI_WRAP(xptro);
1696 xpc = ADDR_MASK(xpc);
1698 /* Fill and add a stackframeinfo (XPC is equal to RA). */
1700 stacktrace_stackframeinfo_add(&sfi, pv, sp, xpc, xpc);
1704 /* Get the codeinfo for the current method. */
1706 code = code_get_codeinfo_for_pv(pv);
1708 /* Get the methodinfo pointer from the codeinfo pointer. For
1709 asm_vm_call_method the codeinfo pointer is NULL and we simply
1710 can return the proper exception handler. */
1713 result = (void *) (uintptr_t) &asm_vm_call_method_exception_handler;
1714 goto exceptions_handle_exception_return;
1719 #if !defined(NDEBUG)
1720 /* print exception trace */
1722 if (opt_TraceExceptions)
1723 trace_exception(LLNI_DIRECT(xptr), m, xpc);
1725 # if defined(ENABLE_VMLOG)
1726 vmlog_cacao_throw(xptr);
1730 /* Get the exception table. */
1732 et = code->exceptiontable;
1735 /* Iterate over all exception table entries. */
1739 for (i = 0; i < et->length; i++, ete++) {
1740 /* is the xpc is the current catch range */
1742 if ((ADDR_MASK(ete->startpc) <= xpc) && (xpc < ADDR_MASK(ete->endpc))) {
1743 cr = ete->catchtype;
1745 /* NULL catches everything */
1747 if (cr.any == NULL) {
1748 #if !defined(NDEBUG)
1749 /* Print stacktrace of exception when caught. */
1751 # if defined(ENABLE_VMLOG)
1752 vmlog_cacao_catch(xptr);
1755 if (opt_TraceExceptions) {
1756 exceptions_print_exception(xptr);
1757 stacktrace_print_exception(xptr);
1761 result = ete->handlerpc;
1762 goto exceptions_handle_exception_return;
1765 /* resolve or load/link the exception class */
1767 if (IS_CLASSREF(cr)) {
1768 /* The exception class reference is unresolved. */
1769 /* We have to do _eager_ resolving here. While the
1770 class of the exception object is guaranteed to be
1771 loaded, it may well have been loaded by a different
1772 loader than the defining loader of m's class, which
1773 is the one we must use to resolve the catch
1774 class. Thus lazy resolving might fail, even if the
1775 result of the resolution would be an already loaded
1778 c = resolve_classref_eager(cr.ref);
1781 /* Exception resolving the exception class, argh! */
1782 goto exceptions_handle_exception_return;
1785 /* Ok, we resolved it. Enter it in the table, so we
1786 don't have to do this again. */
1787 /* XXX this write should be atomic. Is it? */
1789 ete->catchtype.cls = c;
1794 /* XXX I don't think this case can ever happen. -Edwin */
1795 if (!(c->state & CLASS_LOADED))
1796 /* use the methods' classloader */
1797 if (!load_class_from_classloader(c->name,
1798 m->clazz->classloader))
1799 goto exceptions_handle_exception_return;
1801 /* XXX I think, if it is not linked, we can be sure
1802 that the exception object is no (indirect) instance
1803 of it, no? -Edwin */
1804 if (!(c->state & CLASS_LINKED))
1806 goto exceptions_handle_exception_return;
1809 /* is the thrown exception an instance of the catch class? */
1811 if (builtin_instanceof(xptr, c)) {
1812 #if !defined(NDEBUG)
1813 /* Print stacktrace of exception when caught. */
1815 # if defined(ENABLE_VMLOG)
1816 vmlog_cacao_catch(xptr);
1819 if (opt_TraceExceptions) {
1820 exceptions_print_exception(xptr);
1821 stacktrace_print_exception(xptr);
1825 result = ete->handlerpc;
1826 goto exceptions_handle_exception_return;
1832 #if defined(ENABLE_THREADS)
1833 /* Is this method realization synchronized? */
1835 if (code_is_synchronized(code)) {
1836 /* Get synchronization object. */
1838 o = *((java_object_t **) (((uintptr_t) sp) + code->synchronizedoffset));
1842 lock_monitor_exit(LLNI_QUICKWRAP(o));
1846 /* none of the exceptions catch this one */
1848 #if !defined(NDEBUG)
1849 # if defined(ENABLE_VMLOG)
1850 vmlog_cacao_unwnd_method(m);
1853 # if defined(ENABLE_DEBUG_FILTER)
1854 if (show_filters_test_verbosecall_exit(m)) {
1857 /* outdent the log message */
1859 if (opt_verbosecall) {
1860 if (TRACEJAVACALLINDENT)
1861 TRACEJAVACALLINDENT--;
1863 log_text("exceptions_handle_exception: WARNING: unmatched unindent");
1866 # if defined(ENABLE_DEBUG_FILTER)
1869 #endif /* !defined(NDEBUG) */
1873 exceptions_handle_exception_return:
1875 /* Remove the stackframeinfo. */
1877 stacktrace_stackframeinfo_remove(&sfi);
1881 #endif /* defined(ENABLE_JIT) */
1884 /* exceptions_print_exception **************************************************
1886 Prints an exception, the detail message and the cause, if
1887 available, with CACAO internal functions to stdout.
1889 *******************************************************************************/
1891 void exceptions_print_exception(java_handle_t *xptr)
1893 java_lang_Throwable jlt(xptr);
1895 if (jlt.is_null()) {
1900 #if defined(ENABLE_JAVASE)
1901 java_lang_Throwable jltcause(jlt.get_cause());
1904 /* print the root exception */
1906 classinfo* c = jlt.get_Class();
1907 utf_display_printable_ascii_classname(c->name);
1909 java_lang_String jls(jlt.get_detailMessage());
1911 if (!jls.is_null()) {
1912 utf* u = javastring_toutf(jls.get_handle(), false);
1915 utf_display_printable_ascii(u);
1920 #if defined(ENABLE_JAVASE)
1921 /* print the cause if available */
1923 // FIXME cause != t compare with operator override.
1924 if ((!jltcause.is_null()) && (jltcause.get_handle() != jlt.get_handle())) {
1925 printf("Caused by: ");
1927 c = jltcause.get_Class();
1928 utf_display_printable_ascii_classname(c->name);
1930 java_lang_String jlscause(jlt.get_detailMessage());
1932 if (jlscause.get_handle() != NULL) {
1933 utf* u = javastring_toutf(jlscause.get_handle(), false);
1936 utf_display_printable_ascii(u);
1945 /* exceptions_print_current_exception ******************************************
1947 Prints the current pending exception, the detail message and the
1948 cause, if available, with CACAO internal functions to stdout.
1950 *******************************************************************************/
1952 void exceptions_print_current_exception(void)
1956 o = exceptions_get_exception();
1958 exceptions_print_exception(o);
1962 /* exceptions_print_stacktrace *************************************************
1964 Prints a pending exception with Throwable.printStackTrace(). If
1965 there happens an exception during printStackTrace(), we print the
1966 thrown exception and the original one.
1968 NOTE: This function calls Java code.
1970 *******************************************************************************/
1972 void exceptions_print_stacktrace(void)
1979 #if defined(ENABLE_THREADS)
1981 java_lang_Thread *to;
1984 /* Get and clear exception because we are calling Java code
1987 e = exceptions_get_and_clear_exception();
1993 /* FIXME Enable me. */
1994 if (builtin_instanceof(e, class_java_lang_ThreadDeath)) {
1995 /* Don't print anything if we are being killed. */
2000 /* Get the exception class. */
2002 LLNI_class_get(e, c);
2004 /* Find the printStackTrace() method. */
2006 m = class_resolveclassmethod(c,
2007 utf_printStackTrace,
2009 class_java_lang_Object,
2013 os::abort("exceptions_print_stacktrace: printStackTrace()V not found");
2015 /* Print message. */
2017 fprintf(stderr, "Exception ");
2019 #if defined(ENABLE_THREADS)
2020 /* Print thread name. We get the thread here explicitly as we
2021 need it afterwards. */
2023 t = thread_get_current();
2024 to = (java_lang_Thread *) LLNI_WRAP(t->object);
2027 fprintf(stderr, "in thread \"");
2028 thread_fprint_name(t, stderr);
2029 fprintf(stderr, "\" ");
2033 /* Print the stacktrace. */
2035 if (builtin_instanceof(e, class_java_lang_Throwable)) {
2036 (void) vm_call_method(m, e);
2038 /* If this happens we are EXTREMLY out of memory or have a
2039 serious problem while printStackTrace. But may be
2040 another exception, so print it. */
2042 ne = exceptions_get_exception();
2045 fprintf(stderr, "Exception while printStackTrace(): ");
2047 /* Print the current exception. */
2049 exceptions_print_exception(ne);
2050 stacktrace_print_exception(ne);
2052 /* Now print the original exception. */
2054 fprintf(stderr, "Original exception was: ");
2055 exceptions_print_exception(e);
2056 stacktrace_print_exception(e);
2060 fprintf(stderr, ". Uncaught exception of type ");
2061 #if !defined(NDEBUG)
2062 /* FIXME This prints to stdout. */
2065 fprintf(stderr, "UNKNOWN");
2067 fprintf(stderr, ".");
2078 * These are local overrides for various environment variables in Emacs.
2079 * Please do not remove this and leave it at the end of the file, where
2080 * Emacs will automagically detect them.
2081 * ---------------------------------------------------------------------
2084 * indent-tabs-mode: t
2088 * vim:noexpandtab:sw=4:ts=4: