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_init *************************************************************
87 Initialize the exceptions subsystem.
89 *******************************************************************************/
91 void exceptions_init(void)
93 #if !(defined(__ARM__) && defined(__LINUX__))
94 /* On arm-linux the first memory page can't be mmap'ed, as it
95 contains the exception vectors. */
99 /* mmap a memory page at address 0x0, so our hardware-exceptions
102 pagesize = system_getpagesize();
104 (void) system_mmap_anonymous(NULL, pagesize, PROT_NONE, MAP_PRIVATE | MAP_FIXED);
107 TRACESUBSYSTEMINITIALIZATION("exceptions_init");
109 /* check if we get into trouble with our hardware-exceptions */
111 if (OFFSET(java_bytearray_t, data) <= EXCEPTION_HARDWARE_LARGEST)
112 vm_abort("signal_init: array-data offset is less or equal the maximum hardware-exception displacement: %d <= %d", OFFSET(java_bytearray_t, data), EXCEPTION_HARDWARE_LARGEST);
116 /* exceptions_get_exception ****************************************************
118 Returns the current exception pointer of the current thread.
120 *******************************************************************************/
122 java_handle_t *exceptions_get_exception(void)
126 #if defined(ENABLE_THREADS)
132 /* Get the exception. */
136 #if defined(ENABLE_THREADS)
137 o = t->_exceptionptr;
139 o = _no_threads_exceptionptr;
146 /* Return the exception. */
152 /* exceptions_set_exception ****************************************************
154 Sets the exception pointer of the current thread.
156 *******************************************************************************/
158 void exceptions_set_exception(java_handle_t *e)
163 #if defined(ENABLE_THREADS)
169 /* Set the exception. */
176 if (opt_DebugExceptions) {
177 printf("[exceptions_set_exception : t=%p, o=%p, class=",
178 (void *) t, (void *) o);
179 class_print(o->vftbl->class);
184 #if defined(ENABLE_THREADS)
185 t->_exceptionptr = o;
187 _no_threads_exceptionptr = o;
194 /* exceptions_clear_exception **************************************************
196 Clears the current exception pointer of the current thread.
198 *******************************************************************************/
200 void exceptions_clear_exception(void)
204 #if defined(ENABLE_THREADS)
210 /* Set the exception. */
213 if (opt_DebugExceptions) {
214 printf("[exceptions_clear_exception: t=%p]\n", (void *) t);
218 #if defined(ENABLE_THREADS)
219 t->_exceptionptr = NULL;
221 _no_threads_exceptionptr = NULL;
226 /* exceptions_get_and_clear_exception ******************************************
228 Gets the exception pointer of the current thread and clears it.
229 This function may return NULL.
231 *******************************************************************************/
233 java_handle_t *exceptions_get_and_clear_exception(void)
237 /* Get the exception... */
239 o = exceptions_get_exception();
241 /* ...and clear the exception if it is set. */
244 exceptions_clear_exception();
246 /* return the exception */
252 /* exceptions_abort ************************************************************
254 Prints exception to be thrown and aborts.
257 classname....class name
258 message......exception message
260 *******************************************************************************/
262 static void exceptions_abort(utf *classname, utf *message)
264 log_println("exception thrown while VM is initializing: ");
267 utf_display_printable_ascii_classname(classname);
269 if (message != NULL) {
271 utf_display_printable_ascii_classname(message);
276 vm_abort("Aborting...");
280 /* exceptions_new_class_utf ****************************************************
282 Creates an exception object with the given class and initalizes it
283 with the given utf message.
286 c ......... exception class
287 message ... the message as an utf *
290 an exception pointer (in any case -- either it is the newly
291 created exception, or an exception thrown while trying to create
294 *******************************************************************************/
296 static java_handle_t *exceptions_new_class_utf(classinfo *c, utf *message)
302 exceptions_abort(c->name, message);
304 s = javastring_new(message);
307 return exceptions_get_exception();
309 o = native_new_and_init_string(c, s);
312 return exceptions_get_exception();
318 /* exceptions_new_utf **********************************************************
320 Creates an exception object with the given name and initalizes it.
323 classname....class name in UTF-8
325 *******************************************************************************/
327 static java_handle_t *exceptions_new_utf(utf *classname)
333 exceptions_abort(classname, NULL);
335 c = load_class_bootstrap(classname);
338 return exceptions_get_exception();
340 o = native_new_and_init(c);
343 return exceptions_get_exception();
349 /* exceptions_new_utf_javastring ***********************************************
351 Creates an exception object with the given name and initalizes it
352 with the given java/lang/String message.
355 classname....class name in UTF-8
356 message......the message as a java.lang.String
359 an exception pointer (in any case -- either it is the newly created
360 exception, or an exception thrown while trying to create it).
362 *******************************************************************************/
364 static java_handle_t *exceptions_new_utf_javastring(utf *classname,
365 java_handle_t *message)
371 exceptions_abort(classname, NULL);
373 c = load_class_bootstrap(classname);
376 return exceptions_get_exception();
378 o = native_new_and_init_string(c, message);
381 return exceptions_get_exception();
387 /* exceptions_new_utf_utf ******************************************************
389 Creates an exception object with the given name and initalizes it
390 with the given utf message.
393 classname....class name in UTF-8
394 message......the message as an utf *
397 an exception pointer (in any case -- either it is the newly created
398 exception, or an exception thrown while trying to create it).
400 *******************************************************************************/
402 static java_handle_t *exceptions_new_utf_utf(utf *classname, utf *message)
408 exceptions_abort(classname, message);
410 c = load_class_bootstrap(classname);
413 return exceptions_get_exception();
415 o = exceptions_new_class_utf(c, message);
421 /* exceptions_throw_class_utf **************************************************
423 Creates an exception object with the given class, initalizes and
424 throws it with the given utf message.
427 c ......... exception class
428 message ... the message as an utf *
430 *******************************************************************************/
432 static void exceptions_throw_class_utf(classinfo *c, utf *message)
436 o = exceptions_new_class_utf(c, message);
438 exceptions_set_exception(o);
442 /* exceptions_throw_utf ********************************************************
444 Creates an exception object with the given name, initalizes and
448 classname....class name in UTF-8
450 *******************************************************************************/
452 static void exceptions_throw_utf(utf *classname)
456 o = exceptions_new_utf(classname);
461 exceptions_set_exception(o);
465 /* exceptions_throw_utf_throwable **********************************************
467 Creates an exception object with the given name and initalizes it
468 with the given java/lang/Throwable exception.
471 classname....class name in UTF-8
472 cause........the given Throwable
474 *******************************************************************************/
476 static void exceptions_throw_utf_throwable(utf *classname,
477 java_handle_t *cause)
482 java_lang_Throwable *object;
485 exceptions_abort(classname, NULL);
487 object = (java_lang_Throwable *) cause;
489 c = load_class_bootstrap(classname);
501 /* call initializer */
503 m = class_resolveclassmethod(c,
505 utf_java_lang_Throwable__void,
512 (void) vm_call_method(m, o, cause);
514 exceptions_set_exception(o);
518 /* exceptions_throw_utf_exception **********************************************
520 Creates an exception object with the given name and initalizes it
521 with the given java/lang/Exception exception.
524 classname....class name in UTF-8
525 exception....the given Exception
527 *******************************************************************************/
529 static void exceptions_throw_utf_exception(utf *classname,
530 java_handle_t *exception)
537 exceptions_abort(classname, NULL);
539 c = load_class_bootstrap(classname);
551 /* call initializer */
553 m = class_resolveclassmethod(c,
555 utf_java_lang_Exception__V,
562 (void) vm_call_method(m, o, exception);
564 exceptions_set_exception(o);
568 /* exceptions_throw_utf_cause **************************************************
570 Creates an exception object with the given name and initalizes it
571 with the given java/lang/Throwable exception with initCause.
574 classname....class name in UTF-8
575 cause........the given Throwable
577 *******************************************************************************/
579 static void exceptions_throw_utf_cause(utf *classname, java_handle_t *cause)
585 java_lang_Throwable *object;
588 exceptions_abort(classname, NULL);
590 object = (java_lang_Throwable *) cause;
592 c = load_class_bootstrap(classname);
604 /* call initializer */
606 m = class_resolveclassmethod(c,
608 utf_java_lang_String__void,
615 LLNI_field_get_ref(object, detailMessage, s);
617 (void) vm_call_method(m, o, s);
621 m = class_resolveclassmethod(c,
623 utf_java_lang_Throwable__java_lang_Throwable,
630 (void) vm_call_method(m, o, cause);
632 exceptions_set_exception(o);
636 /* exceptions_throw_utf_utf ****************************************************
638 Creates an exception object with the given name, initalizes and
639 throws it with the given utf message.
642 classname....class name in UTF-8
643 message......the message as an utf *
645 *******************************************************************************/
647 static void exceptions_throw_utf_utf(utf *classname, utf *message)
651 o = exceptions_new_utf_utf(classname, message);
653 exceptions_set_exception(o);
657 /* exceptions_new_abstractmethoderror ****************************************
659 Generates a java.lang.AbstractMethodError for the VM.
661 *******************************************************************************/
663 java_handle_t *exceptions_new_abstractmethoderror(void)
667 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
673 /* exceptions_new_error ********************************************************
675 Generates a java.lang.Error for the VM.
677 *******************************************************************************/
679 #if defined(ENABLE_JAVAME_CLDC1_1)
680 static java_handle_t *exceptions_new_error(utf *message)
684 o = exceptions_new_utf_utf(utf_java_lang_Error, message);
691 /* exceptions_asm_new_abstractmethoderror **************************************
693 Generates a java.lang.AbstractMethodError for
694 asm_abstractmethoderror.
696 *******************************************************************************/
698 java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
700 stackframeinfo_t sfi;
704 /* Fill and add a stackframeinfo (XPC is equal to RA). */
706 stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra);
708 /* create the exception */
710 #if defined(ENABLE_JAVASE)
711 e = exceptions_new_abstractmethoderror();
713 e = exceptions_new_error(utf_java_lang_AbstractMethodError);
716 /* Remove the stackframeinfo. */
718 stacktrace_stackframeinfo_remove(&sfi);
720 /* unwrap the exception */
721 /* ATTENTION: do the this _after_ the stackframeinfo was removed */
729 /* exceptions_new_arraystoreexception ******************************************
731 Generates a java.lang.ArrayStoreException for the VM.
733 *******************************************************************************/
735 java_handle_t *exceptions_new_arraystoreexception(void)
739 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
745 /* exceptions_throw_abstractmethoderror ****************************************
747 Generates and throws a java.lang.AbstractMethodError for the VM.
749 *******************************************************************************/
751 void exceptions_throw_abstractmethoderror(void)
753 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
757 /* exceptions_throw_classcircularityerror **************************************
759 Generates and throws a java.lang.ClassCircularityError for the
763 c....the class in which the error was found
765 *******************************************************************************/
767 void exceptions_throw_classcircularityerror(classinfo *c)
769 exceptions_throw_utf_utf(utf_java_lang_ClassCircularityError, c->name);
773 /* exceptions_throw_classformaterror *******************************************
775 Generates and throws a java.lang.ClassFormatError for the VM.
778 c............the class in which the error was found
779 message......UTF-8 format string
781 *******************************************************************************/
783 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
790 /* calculate message length */
795 msglen += utf_bytes(c->name) + strlen(" (");
797 va_start(ap, message);
798 msglen += get_variable_message_length(message, ap);
802 msglen += strlen(")");
804 msglen += strlen("0");
806 /* allocate a buffer */
808 msg = MNEW(char, msglen);
810 /* print message into allocated buffer */
813 utf_copy_classname(msg, c->name);
817 va_start(ap, message);
818 vsprintf(msg + strlen(msg), message, ap);
824 u = utf_new_char(msg);
828 MFREE(msg, char, msglen);
830 /* throw exception */
832 exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
836 /* exceptions_throw_classnotfoundexception *************************************
838 Generates and throws a java.lang.ClassNotFoundException for the
842 name.........name of the class not found as a utf *
844 *******************************************************************************/
846 void exceptions_throw_classnotfoundexception(utf *name)
848 exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
852 /* exceptions_throw_noclassdeffounderror ***************************************
854 Generates and throws a java.lang.NoClassDefFoundError.
857 name.........name of the class not found as a utf *
859 *******************************************************************************/
861 void exceptions_throw_noclassdeffounderror(utf *name)
863 exceptions_throw_utf_utf(utf_java_lang_NoClassDefFoundError, name);
867 /* exceptions_throw_noclassdeffounderror_cause *********************************
869 Generates and throws a java.lang.NoClassDefFoundError with the
872 *******************************************************************************/
874 void exceptions_throw_noclassdeffounderror_cause(java_handle_t *cause)
876 exceptions_throw_utf_cause(utf_java_lang_NoClassDefFoundError, cause);
880 /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
882 Generates and throws a java.lang.NoClassDefFoundError with a
886 name.........name of the class not found as a utf *
888 *******************************************************************************/
890 void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
896 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
897 utf_bytes(name) + strlen(")") + strlen("0");
899 msg = MNEW(char, msglen);
901 utf_copy_classname(msg, c->name);
902 strcat(msg, " (wrong name: ");
903 utf_cat_classname(msg, name);
906 u = utf_new_char(msg);
908 MFREE(msg, char, msglen);
910 exceptions_throw_noclassdeffounderror(u);
914 /* exceptions_throw_exceptionininitializererror ********************************
916 Generates and throws a java.lang.ExceptionInInitializerError for
920 cause......cause exception object
922 *******************************************************************************/
924 void exceptions_throw_exceptionininitializererror(java_handle_t *cause)
926 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
931 /* exceptions_throw_incompatibleclasschangeerror *******************************
933 Generates and throws a java.lang.IncompatibleClassChangeError for
937 message......UTF-8 message format string
939 *******************************************************************************/
941 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
947 /* calculate exception message length */
949 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
951 /* allocate memory */
953 msg = MNEW(char, msglen);
955 utf_copy_classname(msg, c->name);
956 strcat(msg, message);
958 u = utf_new_char(msg);
962 MFREE(msg, char, msglen);
964 /* throw exception */
966 exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
970 /* exceptions_throw_instantiationerror *****************************************
972 Generates and throws a java.lang.InstantiationError for the VM.
974 *******************************************************************************/
976 void exceptions_throw_instantiationerror(classinfo *c)
978 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
982 /* exceptions_throw_internalerror **********************************************
984 Generates and throws a java.lang.InternalError for the VM.
987 message......UTF-8 message format string
989 *******************************************************************************/
991 void exceptions_throw_internalerror(const char *message, ...)
998 /* calculate exception message length */
1000 va_start(ap, message);
1001 msglen = get_variable_message_length(message, ap);
1004 /* allocate memory */
1006 msg = MNEW(char, msglen);
1008 /* generate message */
1010 va_start(ap, message);
1011 vsprintf(msg, message, ap);
1014 u = utf_new_char(msg);
1018 MFREE(msg, char, msglen);
1020 /* throw exception */
1022 exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
1026 /* exceptions_throw_linkageerror ***********************************************
1028 Generates and throws java.lang.LinkageError with an error message.
1031 message......UTF-8 message
1032 c............class related to the error. If this is != NULL
1033 the name of c is appended to the error message.
1035 *******************************************************************************/
1037 void exceptions_throw_linkageerror(const char *message, classinfo *c)
1043 /* calculate exception message length */
1045 len = strlen(message) + 1;
1048 len += utf_bytes(c->name);
1050 /* allocate memory */
1052 msg = MNEW(char, len);
1054 /* generate message */
1056 strcpy(msg, message);
1059 utf_cat_classname(msg, c->name);
1061 u = utf_new_char(msg);
1065 MFREE(msg, char, len);
1067 exceptions_throw_utf_utf(utf_java_lang_LinkageError, u);
1071 /* exceptions_throw_nosuchfielderror *******************************************
1073 Generates and throws a java.lang.NoSuchFieldError with an error
1077 c............class in which the field was not found
1078 name.........name of the field
1080 *******************************************************************************/
1082 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
1088 /* calculate exception message length */
1090 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
1092 /* allocate memory */
1094 msg = MNEW(char, msglen);
1096 /* generate message */
1098 utf_copy_classname(msg, c->name);
1102 u = utf_new_char(msg);
1106 MFREE(msg, char, msglen);
1108 exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
1112 /* exceptions_throw_nosuchmethoderror ******************************************
1114 Generates and throws a java.lang.NoSuchMethodError with an error
1118 c............class in which the method was not found
1119 name.........name of the method
1120 desc.........descriptor of the method
1122 *******************************************************************************/
1124 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
1130 /* calculate exception message length */
1132 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
1133 utf_bytes(desc) + strlen("0");
1135 /* allocate memory */
1137 msg = MNEW(char, msglen);
1139 /* generate message */
1141 utf_copy_classname(msg, c->name);
1146 u = utf_new_char(msg);
1150 MFREE(msg, char, msglen);
1152 #if defined(ENABLE_JAVASE)
1153 exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
1155 exceptions_throw_utf_utf(utf_java_lang_Error, u);
1160 /* exceptions_throw_outofmemoryerror *******************************************
1162 Generates and throws an java.lang.OutOfMemoryError for the VM.
1164 *******************************************************************************/
1166 void exceptions_throw_outofmemoryerror(void)
1168 exceptions_throw_utf(utf_java_lang_OutOfMemoryError);
1172 /* exceptions_throw_unsatisfiedlinkerror ***************************************
1174 Generates and throws a java.lang.UnsatisfiedLinkError for the
1178 name......UTF-8 name string
1180 *******************************************************************************/
1182 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1184 #if defined(ENABLE_JAVASE)
1185 exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1187 exceptions_throw_utf_utf(utf_java_lang_Error, name);
1192 /* exceptions_throw_unsupportedclassversionerror *******************************
1194 Generates and throws a java.lang.UnsupportedClassVersionError for
1198 c............class in which the method was not found
1199 message......UTF-8 format string
1201 *******************************************************************************/
1203 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1209 /* calculate exception message length */
1212 utf_bytes(c->name) +
1213 strlen(" (Unsupported major.minor version 00.0)") +
1216 /* allocate memory */
1218 msg = MNEW(char, msglen);
1220 /* generate message */
1222 utf_copy_classname(msg, c->name);
1223 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1226 u = utf_new_char(msg);
1230 MFREE(msg, char, msglen);
1232 /* throw exception */
1234 exceptions_throw_utf_utf(utf_java_lang_UnsupportedClassVersionError, u);
1238 /* exceptions_throw_verifyerror ************************************************
1240 Generates and throws a java.lang.VerifyError for the JIT compiler.
1243 m............method in which the error was found
1244 message......UTF-8 format string
1246 *******************************************************************************/
1248 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1255 /* calculate exception message length */
1261 strlen("(class: ") + utf_bytes(m->class->name) +
1262 strlen(", method: ") + utf_bytes(m->name) +
1263 strlen(" signature: ") + utf_bytes(m->descriptor) +
1264 strlen(") ") + strlen("0");
1266 va_start(ap, message);
1267 msglen += get_variable_message_length(message, ap);
1270 /* allocate memory */
1272 msg = MNEW(char, msglen);
1274 /* generate message */
1277 strcpy(msg, "(class: ");
1278 utf_cat_classname(msg, m->class->name);
1279 strcat(msg, ", method: ");
1280 utf_cat(msg, m->name);
1281 strcat(msg, " signature: ");
1282 utf_cat(msg, m->descriptor);
1286 va_start(ap, message);
1287 vsprintf(msg + strlen(msg), message, ap);
1290 u = utf_new_char(msg);
1294 MFREE(msg, char, msglen);
1296 /* throw exception */
1298 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1302 /* exceptions_throw_verifyerror_for_stack **************************************
1304 throws a java.lang.VerifyError for an invalid stack slot type
1307 m............method in which the error was found
1308 type.........the expected type
1311 an exception pointer (in any case -- either it is the newly created
1312 exception, or an exception thrown while trying to create it).
1314 *******************************************************************************/
1316 void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
1323 /* calculate exception message length */
1328 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1329 strlen(", method: ") + utf_bytes(m->name) +
1330 strlen(" signature: ") + utf_bytes(m->descriptor) +
1331 strlen(") Expecting to find longest-------typename on stack")
1334 /* allocate memory */
1336 msg = MNEW(char, msglen);
1338 /* generate message */
1341 strcpy(msg, "(class: ");
1342 utf_cat_classname(msg, m->class->name);
1343 strcat(msg, ", method: ");
1344 utf_cat(msg, m->name);
1345 strcat(msg, " signature: ");
1346 utf_cat(msg, m->descriptor);
1353 strcat(msg, "Expecting to find ");
1356 case TYPE_INT: typename = "integer"; break;
1357 case TYPE_LNG: typename = "long"; break;
1358 case TYPE_FLT: typename = "float"; break;
1359 case TYPE_DBL: typename = "double"; break;
1360 case TYPE_ADR: typename = "object/array"; break;
1361 case TYPE_RET: typename = "returnAddress"; break;
1362 default: typename = "<INVALID>"; assert(0); break;
1365 strcat(msg, typename);
1366 strcat(msg, " on stack");
1368 u = utf_new_char(msg);
1372 MFREE(msg, char, msglen);
1374 /* throw exception */
1376 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1380 /* exceptions_new_arithmeticexception ******************************************
1382 Generates a java.lang.ArithmeticException for the JIT compiler.
1384 *******************************************************************************/
1386 java_handle_t *exceptions_new_arithmeticexception(void)
1390 o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
1391 utf_division_by_zero);
1397 /* exceptions_new_arrayindexoutofboundsexception *******************************
1399 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1402 *******************************************************************************/
1404 java_handle_t *exceptions_new_arrayindexoutofboundsexception(s4 index)
1410 /* convert the index into a String, like Sun does */
1412 m = class_resolveclassmethod(class_java_lang_String,
1413 utf_new_char("valueOf"),
1414 utf_new_char("(I)Ljava/lang/String;"),
1415 class_java_lang_Object,
1419 return exceptions_get_exception();
1421 s = vm_call_method(m, NULL, index);
1424 return exceptions_get_exception();
1426 o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1430 return exceptions_get_exception();
1436 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1438 Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1441 *******************************************************************************/
1443 void exceptions_throw_arrayindexoutofboundsexception(void)
1445 exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1449 /* exceptions_throw_arraystoreexception ****************************************
1451 Generates and throws a java.lang.ArrayStoreException for the VM.
1453 *******************************************************************************/
1455 void exceptions_throw_arraystoreexception(void)
1457 exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1461 /* exceptions_new_classcastexception *******************************************
1463 Generates a java.lang.ClassCastException for the JIT compiler.
1465 *******************************************************************************/
1467 java_handle_t *exceptions_new_classcastexception(java_handle_t *o)
1473 LLNI_class_get(o, c);
1475 classname = c->name;
1477 e = exceptions_new_utf_utf(utf_java_lang_ClassCastException, classname);
1483 /* exceptions_throw_clonenotsupportedexception *********************************
1485 Generates and throws a java.lang.CloneNotSupportedException for the
1488 *******************************************************************************/
1490 void exceptions_throw_clonenotsupportedexception(void)
1492 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1496 /* exceptions_throw_illegalaccessexception *************************************
1498 Generates and throws a java.lang.IllegalAccessException for the VM.
1500 *******************************************************************************/
1502 void exceptions_throw_illegalaccessexception(utf *message)
1504 exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
1508 /* exceptions_throw_illegalargumentexception ***********************************
1510 Generates and throws a java.lang.IllegalArgumentException for the
1513 *******************************************************************************/
1515 void exceptions_throw_illegalargumentexception(void)
1517 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1521 /* exceptions_throw_illegalmonitorstateexception *******************************
1523 Generates and throws a java.lang.IllegalMonitorStateException for
1526 *******************************************************************************/
1528 void exceptions_throw_illegalmonitorstateexception(void)
1530 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1534 /* exceptions_throw_instantiationexception *************************************
1536 Generates and throws a java.lang.InstantiationException for the VM.
1538 *******************************************************************************/
1540 void exceptions_throw_instantiationexception(classinfo *c)
1542 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1546 /* exceptions_throw_interruptedexception ***************************************
1548 Generates and throws a java.lang.InterruptedException for the VM.
1550 *******************************************************************************/
1552 void exceptions_throw_interruptedexception(void)
1554 exceptions_throw_utf(utf_java_lang_InterruptedException);
1558 /* exceptions_throw_invocationtargetexception **********************************
1560 Generates and throws a java.lang.reflect.InvocationTargetException
1564 cause......cause exception object
1566 *******************************************************************************/
1568 void exceptions_throw_invocationtargetexception(java_handle_t *cause)
1570 exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1575 /* exceptions_throw_negativearraysizeexception *********************************
1577 Generates and throws a java.lang.NegativeArraySizeException for the
1580 *******************************************************************************/
1582 void exceptions_throw_negativearraysizeexception(void)
1584 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1588 /* exceptions_new_nullpointerexception *****************************************
1590 Generates a java.lang.NullPointerException for the VM system.
1592 *******************************************************************************/
1594 java_handle_t *exceptions_new_nullpointerexception(void)
1598 o = exceptions_new_utf(utf_java_lang_NullPointerException);
1604 /* exceptions_throw_nullpointerexception ***************************************
1606 Generates a java.lang.NullPointerException for the VM system and
1607 throw it in the VM system.
1609 *******************************************************************************/
1611 void exceptions_throw_nullpointerexception(void)
1613 exceptions_throw_utf(utf_java_lang_NullPointerException);
1617 /* exceptions_throw_privilegedactionexception **********************************
1619 Generates and throws a java.security.PrivilegedActionException.
1621 *******************************************************************************/
1623 void exceptions_throw_privilegedactionexception(java_handle_t *exception)
1625 exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
1630 /* exceptions_throw_stringindexoutofboundsexception ****************************
1632 Generates and throws a java.lang.StringIndexOutOfBoundsException
1635 *******************************************************************************/
1637 void exceptions_throw_stringindexoutofboundsexception(void)
1639 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1643 /* exceptions_fillinstacktrace *************************************************
1645 Calls the fillInStackTrace-method of the currently thrown
1648 *******************************************************************************/
1650 java_handle_t *exceptions_fillinstacktrace(void)
1658 o = exceptions_get_and_clear_exception();
1662 /* resolve methodinfo pointer from exception object */
1664 LLNI_class_get(o, c);
1666 #if defined(ENABLE_JAVASE)
1667 m = class_resolvemethod(c,
1668 utf_fillInStackTrace,
1669 utf_void__java_lang_Throwable);
1670 #elif defined(ENABLE_JAVAME_CLDC1_1)
1671 m = class_resolvemethod(c,
1672 utf_fillInStackTrace,
1675 #error IMPLEMENT ME!
1680 (void) vm_call_method(m, o);
1682 /* return exception object */
1688 /* exceptions_handle_exception *************************************************
1690 Try to find an exception handler for the given exception and return it.
1691 If no handler is found, exit the monitor of the method (if any)
1695 xptr.........the exception object
1696 xpc..........PC of where the exception was thrown
1697 pv...........Procedure Value of the current method
1698 sp...........current stack pointer
1701 the address of the first matching exception handler, or
1702 NULL if no handler was found
1704 *******************************************************************************/
1706 #if defined(ENABLE_JIT)
1707 void *exceptions_handle_exception(java_object_t *xptro, void *xpc, void *pv, void *sp)
1709 stackframeinfo_t sfi;
1710 java_handle_t *xptr;
1713 exceptiontable_t *et;
1714 exceptiontable_entry_t *ete;
1716 classref_or_classinfo cr;
1718 #if defined(ENABLE_THREADS)
1724 /* Addresses are 31 bit integers */
1725 # define ADDR_MASK(x) (void *) ((uintptr_t) (x) & 0x7FFFFFFF)
1727 # define ADDR_MASK(x) (x)
1730 xptr = LLNI_WRAP(xptro);
1731 xpc = ADDR_MASK(xpc);
1733 /* Fill and add a stackframeinfo (XPC is equal to RA). */
1735 stacktrace_stackframeinfo_add(&sfi, pv, sp, xpc, xpc);
1739 /* Get the codeinfo for the current method. */
1741 code = code_get_codeinfo_for_pv(pv);
1743 /* Get the methodinfo pointer from the codeinfo pointer. For
1744 asm_vm_call_method the codeinfo pointer is NULL and we simply
1745 can return the proper exception handler. */
1748 result = (void *) (uintptr_t) &asm_vm_call_method_exception_handler;
1749 goto exceptions_handle_exception_return;
1754 #if !defined(NDEBUG)
1755 /* print exception trace */
1757 if (opt_TraceExceptions)
1758 trace_exception(LLNI_DIRECT(xptr), m, xpc);
1760 # if defined(ENABLE_VMLOG)
1761 vmlog_cacao_throw(xptr);
1765 /* Get the exception table. */
1767 et = code->exceptiontable;
1770 /* Iterate over all exception table entries. */
1774 for (i = 0; i < et->length; i++, ete++) {
1775 /* is the xpc is the current catch range */
1777 if ((ADDR_MASK(ete->startpc) <= xpc) && (xpc < ADDR_MASK(ete->endpc))) {
1778 cr = ete->catchtype;
1780 /* NULL catches everything */
1782 if (cr.any == NULL) {
1783 #if !defined(NDEBUG)
1784 /* Print stacktrace of exception when caught. */
1786 # if defined(ENABLE_VMLOG)
1787 vmlog_cacao_catch(xptr);
1790 if (opt_TraceExceptions) {
1791 exceptions_print_exception(xptr);
1792 stacktrace_print_exception(xptr);
1796 result = ete->handlerpc;
1797 goto exceptions_handle_exception_return;
1800 /* resolve or load/link the exception class */
1802 if (IS_CLASSREF(cr)) {
1803 /* The exception class reference is unresolved. */
1804 /* We have to do _eager_ resolving here. While the
1805 class of the exception object is guaranteed to be
1806 loaded, it may well have been loaded by a different
1807 loader than the defining loader of m's class, which
1808 is the one we must use to resolve the catch
1809 class. Thus lazy resolving might fail, even if the
1810 result of the resolution would be an already loaded
1813 c = resolve_classref_eager(cr.ref);
1816 /* Exception resolving the exception class, argh! */
1817 goto exceptions_handle_exception_return;
1820 /* Ok, we resolved it. Enter it in the table, so we
1821 don't have to do this again. */
1822 /* XXX this write should be atomic. Is it? */
1824 ete->catchtype.cls = c;
1829 /* XXX I don't think this case can ever happen. -Edwin */
1830 if (!(c->state & CLASS_LOADED))
1831 /* use the methods' classloader */
1832 if (!load_class_from_classloader(c->name,
1833 m->class->classloader))
1834 goto exceptions_handle_exception_return;
1836 /* XXX I think, if it is not linked, we can be sure
1837 that the exception object is no (indirect) instance
1838 of it, no? -Edwin */
1839 if (!(c->state & CLASS_LINKED))
1841 goto exceptions_handle_exception_return;
1844 /* is the thrown exception an instance of the catch class? */
1846 if (builtin_instanceof(xptr, c)) {
1847 #if !defined(NDEBUG)
1848 /* Print stacktrace of exception when caught. */
1850 # if defined(ENABLE_VMLOG)
1851 vmlog_cacao_catch(xptr);
1854 if (opt_TraceExceptions) {
1855 exceptions_print_exception(xptr);
1856 stacktrace_print_exception(xptr);
1860 result = ete->handlerpc;
1861 goto exceptions_handle_exception_return;
1867 #if defined(ENABLE_THREADS)
1868 /* Is this method realization synchronized? */
1870 if (code_is_synchronized(code)) {
1871 /* Get synchronization object. */
1873 o = *((java_object_t **) (((uintptr_t) sp) + code->synchronizedoffset));
1877 lock_monitor_exit(LLNI_QUICKWRAP(o));
1881 /* none of the exceptions catch this one */
1883 #if !defined(NDEBUG)
1884 # if defined(ENABLE_VMLOG)
1885 vmlog_cacao_unwnd_method(m);
1888 # if defined(ENABLE_DEBUG_FILTER)
1889 if (show_filters_test_verbosecall_exit(m)) {
1892 /* outdent the log message */
1894 if (opt_verbosecall) {
1895 if (TRACEJAVACALLINDENT)
1896 TRACEJAVACALLINDENT--;
1898 log_text("exceptions_handle_exception: WARNING: unmatched unindent");
1901 # if defined(ENABLE_DEBUG_FILTER)
1904 #endif /* !defined(NDEBUG) */
1908 exceptions_handle_exception_return:
1910 /* Remove the stackframeinfo. */
1912 stacktrace_stackframeinfo_remove(&sfi);
1916 #endif /* defined(ENABLE_JIT) */
1919 /* exceptions_print_exception **************************************************
1921 Prints an exception, the detail message and the cause, if
1922 available, with CACAO internal functions to stdout.
1924 *******************************************************************************/
1926 void exceptions_print_exception(java_handle_t *xptr)
1928 java_lang_Throwable *t;
1929 #if defined(ENABLE_JAVASE)
1930 java_lang_Throwable *cause;
1932 java_lang_String *s;
1936 t = (java_lang_Throwable *) xptr;
1943 #if defined(ENABLE_JAVASE)
1944 LLNI_field_get_ref(t, cause, cause);
1947 /* print the root exception */
1949 LLNI_class_get(t, c);
1950 utf_display_printable_ascii_classname(c->name);
1952 LLNI_field_get_ref(t, detailMessage, s);
1955 u = javastring_toutf((java_handle_t *) s, false);
1958 utf_display_printable_ascii(u);
1963 #if defined(ENABLE_JAVASE)
1964 /* print the cause if available */
1966 if ((cause != NULL) && (cause != t)) {
1967 printf("Caused by: ");
1969 LLNI_class_get(cause, c);
1970 utf_display_printable_ascii_classname(c->name);
1972 LLNI_field_get_ref(cause, detailMessage, s);
1975 u = javastring_toutf((java_handle_t *) s, false);
1978 utf_display_printable_ascii(u);
1987 /* exceptions_print_current_exception ******************************************
1989 Prints the current pending exception, the detail message and the
1990 cause, if available, with CACAO internal functions to stdout.
1992 *******************************************************************************/
1994 void exceptions_print_current_exception(void)
1998 o = exceptions_get_exception();
2000 exceptions_print_exception(o);
2004 /* exceptions_print_stacktrace *************************************************
2006 Prints a pending exception with Throwable.printStackTrace(). If
2007 there happens an exception during printStackTrace(), we print the
2008 thrown exception and the original one.
2010 NOTE: This function calls Java code.
2012 *******************************************************************************/
2014 void exceptions_print_stacktrace(void)
2021 #if defined(ENABLE_THREADS)
2023 java_lang_Thread *to;
2026 /* Get and clear exception because we are calling Java code
2029 e = exceptions_get_and_clear_exception();
2035 /* FIXME Enable me. */
2036 if (builtin_instanceof(e, class_java_lang_ThreadDeath)) {
2037 /* Don't print anything if we are being killed. */
2042 /* Get the exception class. */
2044 LLNI_class_get(e, c);
2046 /* Find the printStackTrace() method. */
2048 m = class_resolveclassmethod(c,
2049 utf_printStackTrace,
2051 class_java_lang_Object,
2055 vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
2057 /* Print message. */
2059 fprintf(stderr, "Exception ");
2061 #if defined(ENABLE_THREADS)
2062 /* Print thread name. We get the thread here explicitly as we
2063 need it afterwards. */
2065 t = thread_get_current();
2066 to = (java_lang_Thread *) thread_get_object(t);
2069 fprintf(stderr, "in thread \"");
2070 thread_fprint_name(t, stderr);
2071 fprintf(stderr, "\" ");
2075 /* Print the stacktrace. */
2077 if (builtin_instanceof(e, class_java_lang_Throwable)) {
2078 (void) vm_call_method(m, e);
2080 /* If this happens we are EXTREMLY out of memory or have a
2081 serious problem while printStackTrace. But may be
2082 another exception, so print it. */
2084 ne = exceptions_get_exception();
2087 fprintf(stderr, "Exception while printStackTrace(): ");
2089 /* Print the current exception. */
2091 exceptions_print_exception(ne);
2092 stacktrace_print_exception(ne);
2094 /* Now print the original exception. */
2096 fprintf(stderr, "Original exception was: ");
2097 exceptions_print_exception(e);
2098 stacktrace_print_exception(e);
2102 fprintf(stderr, ". Uncaught exception of type ");
2103 /* FIXME This prints to stdout. */
2105 fprintf(stderr, ".");
2114 * These are local overrides for various environment variables in Emacs.
2115 * Please do not remove this and leave it at the end of the file, where
2116 * Emacs will automagically detect them.
2117 * ---------------------------------------------------------------------
2120 * indent-tabs-mode: t
2124 * vim:noexpandtab:sw=4:ts=4: