1 /* src/vm/exceptions.c - exception related functions
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
41 #include "mm/memory.h"
43 #include "native/jni.h"
44 #include "native/llni.h"
45 #include "native/native.h"
47 #include "native/include/java_lang_String.h"
48 #include "native/include/java_lang_Throwable.h"
50 #include "threads/lock-common.h"
51 #include "threads/threads-common.h"
53 #include "toolbox/util.h"
55 #include "vm/builtin.h"
56 #include "vm/exceptions.h"
57 #include "vm/global.h"
58 #include "vm/stringlocal.h"
61 #include "vm/jit/asmpart.h"
62 #include "vm/jit/jit.h"
63 #include "vm/jit/methodheader.h"
64 #include "vm/jit/patcher-common.h"
65 #include "vm/jit/stacktrace.h"
67 #include "vmcore/class.h"
68 #include "vmcore/loader.h"
69 #include "vmcore/method.h"
70 #include "vmcore/options.h"
72 #if defined(ENABLE_VMLOG)
73 #include <vmlog_cacao.h>
77 /* for raising exceptions from native methods *********************************/
79 #if !defined(ENABLE_THREADS)
80 java_object_t *_no_threads_exceptionptr = NULL;
84 /* init_system_exceptions ******************************************************
86 Load and link exceptions used in the system.
88 *******************************************************************************/
90 bool exceptions_init(void)
92 #if !(defined(__ARM__) && defined(__LINUX__))
93 /* On arm-linux the first memory page can't be mmap'ed, as it
94 contains the exception vectors. */
98 /* mmap a memory page at address 0x0, so our hardware-exceptions
101 pagesize = getpagesize();
103 (void) memory_mmap_anon(NULL, pagesize, PROT_NONE, MAP_PRIVATE | MAP_FIXED);
106 /* check if we get into trouble with our hardware-exceptions */
108 if (OFFSET(java_bytearray_t, data) <= EXCEPTION_HARDWARE_LARGEST)
109 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);
111 /* java/lang/Throwable */
113 if (!(class_java_lang_Throwable =
114 load_class_bootstrap(utf_java_lang_Throwable)) ||
115 !link_class(class_java_lang_Throwable))
118 /* java/lang/Error */
120 if (!(class_java_lang_Error = load_class_bootstrap(utf_java_lang_Error)) ||
121 !link_class(class_java_lang_Error))
124 #if defined(ENABLE_JAVASE)
125 /* java/lang/LinkageError */
127 if (!(class_java_lang_LinkageError =
128 load_class_bootstrap(utf_java_lang_LinkageError)) ||
129 !link_class(class_java_lang_LinkageError))
133 /* java/lang/NoClassDefFoundError */
135 if (!(class_java_lang_NoClassDefFoundError =
136 load_class_bootstrap(utf_java_lang_NoClassDefFoundError)) ||
137 !link_class(class_java_lang_NoClassDefFoundError))
140 /* java/lang/OutOfMemoryError */
142 if (!(class_java_lang_OutOfMemoryError =
143 load_class_bootstrap(utf_java_lang_OutOfMemoryError)) ||
144 !link_class(class_java_lang_OutOfMemoryError))
147 /* java/lang/VirtualMachineError */
149 if (!(class_java_lang_VirtualMachineError =
150 load_class_bootstrap(utf_java_lang_VirtualMachineError)) ||
151 !link_class(class_java_lang_VirtualMachineError))
155 /* java/lang/Exception */
157 if (!(class_java_lang_Exception =
158 load_class_bootstrap(utf_java_lang_Exception)) ||
159 !link_class(class_java_lang_Exception))
162 /* java/lang/ClassCastException */
164 if (!(class_java_lang_ClassCastException =
165 load_class_bootstrap(utf_java_lang_ClassCastException)) ||
166 !link_class(class_java_lang_ClassCastException))
169 /* java/lang/ClassNotFoundException */
171 if (!(class_java_lang_ClassNotFoundException =
172 load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
173 !link_class(class_java_lang_ClassNotFoundException))
176 /* java/lang/NullPointerException */
178 if (!(class_java_lang_NullPointerException =
179 load_class_bootstrap(utf_java_lang_NullPointerException)) ||
180 !link_class(class_java_lang_NullPointerException))
184 #if defined(WITH_CLASSPATH_GNU)
185 /* java/lang/VMThrowable */
187 if (!(class_java_lang_VMThrowable =
188 load_class_bootstrap(utf_java_lang_VMThrowable)) ||
189 !link_class(class_java_lang_VMThrowable))
197 /* exceptions_get_exception ****************************************************
199 Returns the current exception pointer of the current thread.
201 *******************************************************************************/
203 java_handle_t *exceptions_get_exception(void)
205 /* return the exception */
207 return *exceptionptr;
211 /* exceptions_set_exception ****************************************************
213 Sets the exception pointer of the current thread.
215 *******************************************************************************/
217 void exceptions_set_exception(java_handle_t *o)
219 /* set the exception */
225 /* exceptions_clear_exception **************************************************
227 Clears the current exception pointer of the current thread.
229 *******************************************************************************/
231 void exceptions_clear_exception(void)
233 exceptions_set_exception(NULL);
237 /* exceptions_get_and_clear_exception ******************************************
239 Gets the exception pointer of the current thread and clears it.
240 This function may return NULL.
242 *******************************************************************************/
244 java_handle_t *exceptions_get_and_clear_exception(void)
248 /* get the exception */
250 o = exceptions_get_exception();
252 /* and clear the exception */
254 exceptions_clear_exception();
256 /* return the exception */
262 /* exceptions_new_class ********************************************************
264 Creates an exception object from the given class and initalizes it.
267 class....class pointer
269 *******************************************************************************/
271 static java_handle_t *exceptions_new_class(classinfo *c)
275 o = native_new_and_init(c);
278 return exceptions_get_exception();
284 /* exceptions_new_utf **********************************************************
286 Creates an exception object with the given name and initalizes it.
289 classname....class name in UTF-8
291 *******************************************************************************/
293 static java_handle_t *exceptions_new_utf(utf *classname)
298 c = load_class_bootstrap(classname);
301 return exceptions_get_exception();
303 o = exceptions_new_class(c);
309 /* exceptions_throw_class ******************************************************
311 Creates an exception object from the given class, initalizes and
315 class....class pointer
317 *******************************************************************************/
319 static void exceptions_throw_class(classinfo *c)
323 o = exceptions_new_class(c);
328 exceptions_set_exception(o);
332 /* exceptions_throw_utf ********************************************************
334 Creates an exception object with the given name, initalizes and
338 classname....class name in UTF-8
340 *******************************************************************************/
342 static void exceptions_throw_utf(utf *classname)
346 c = load_class_bootstrap(classname);
351 exceptions_throw_class(c);
355 /* exceptions_throw_utf_throwable **********************************************
357 Creates an exception object with the given name and initalizes it
358 with the given java/lang/Throwable exception.
361 classname....class name in UTF-8
362 cause........the given Throwable
364 *******************************************************************************/
366 static void exceptions_throw_utf_throwable(utf *classname,
367 java_handle_t *cause)
372 java_lang_Throwable *object;
374 object = (java_lang_Throwable *) cause;
376 c = load_class_bootstrap(classname);
388 /* call initializer */
390 m = class_resolveclassmethod(c,
392 utf_java_lang_Throwable__void,
399 (void) vm_call_method(m, o, cause);
401 exceptions_set_exception(o);
405 /* exceptions_throw_utf_exception **********************************************
407 Creates an exception object with the given name and initalizes it
408 with the given java/lang/Exception exception.
411 classname....class name in UTF-8
412 exception....the given Exception
414 *******************************************************************************/
416 static void exceptions_throw_utf_exception(utf *classname,
417 java_handle_t *exception)
423 c = load_class_bootstrap(classname);
435 /* call initializer */
437 m = class_resolveclassmethod(c,
439 utf_java_lang_Exception__V,
446 (void) vm_call_method(m, o, exception);
448 exceptions_set_exception(o);
452 /* exceptions_throw_utf_cause **************************************************
454 Creates an exception object with the given name and initalizes it
455 with the given java/lang/Throwable exception with initCause.
458 classname....class name in UTF-8
459 cause........the given Throwable
461 *******************************************************************************/
463 static void exceptions_throw_utf_cause(utf *classname, java_handle_t *cause)
469 java_lang_Throwable *object;
471 object = (java_lang_Throwable *) cause;
473 c = load_class_bootstrap(classname);
485 /* call initializer */
487 m = class_resolveclassmethod(c,
489 utf_java_lang_String__void,
496 LLNI_field_get_ref(object, detailMessage, s);
498 (void) vm_call_method(m, o, s);
502 m = class_resolveclassmethod(c,
504 utf_java_lang_Throwable__java_lang_Throwable,
511 (void) vm_call_method(m, o, cause);
513 exceptions_set_exception(o);
517 /* exceptions_new_utf_javastring ***********************************************
519 Creates an exception object with the given name and initalizes it
520 with the given java/lang/String message.
523 classname....class name in UTF-8
524 message......the message as a java.lang.String
527 an exception pointer (in any case -- either it is the newly created
528 exception, or an exception thrown while trying to create it).
530 *******************************************************************************/
532 static java_handle_t *exceptions_new_utf_javastring(utf *classname,
533 java_handle_t *message)
538 c = load_class_bootstrap(classname);
541 return exceptions_get_exception();
543 o = native_new_and_init_string(c, message);
546 return exceptions_get_exception();
552 /* exceptions_new_class_utf ****************************************************
554 Creates an exception object of the given class and initalizes it.
557 c..........class pointer
558 message....the message as UTF-8 string
560 *******************************************************************************/
562 static java_handle_t *exceptions_new_class_utf(classinfo *c, utf *message)
567 s = javastring_new(message);
570 return exceptions_get_exception();
572 o = native_new_and_init_string(c, s);
575 return exceptions_get_exception();
581 /* exceptions_new_utf_utf ******************************************************
583 Creates an exception object with the given name and initalizes it
584 with the given utf message.
587 classname....class name in UTF-8
588 message......the message as an utf *
591 an exception pointer (in any case -- either it is the newly created
592 exception, or an exception thrown while trying to create it).
594 *******************************************************************************/
596 static java_handle_t *exceptions_new_utf_utf(utf *classname, utf *message)
601 c = load_class_bootstrap(classname);
604 return exceptions_get_exception();
606 o = exceptions_new_class_utf(c, message);
612 /* exceptions_throw_class_utf **************************************************
614 Creates an exception object of the given class, initalizes and
615 throws it with the given utf message.
618 c..........class pointer
619 message....the message as an UTF-8
621 *******************************************************************************/
623 static void exceptions_throw_class_utf(classinfo *c, utf *message)
627 o = exceptions_new_class_utf(c, message);
629 exceptions_set_exception(o);
633 /* exceptions_throw_utf_utf ****************************************************
635 Creates an exception object with the given name, initalizes and
636 throws it with the given utf message.
639 classname....class name in UTF-8
640 message......the message as an utf *
642 *******************************************************************************/
644 static void exceptions_throw_utf_utf(utf *classname, utf *message)
648 o = exceptions_new_utf_utf(classname, message);
650 exceptions_set_exception(o);
654 /* exceptions_new_abstractmethoderror ****************************************
656 Generates a java.lang.AbstractMethodError for the VM.
658 *******************************************************************************/
660 java_handle_t *exceptions_new_abstractmethoderror(void)
664 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
670 /* exceptions_new_error ********************************************************
672 Generates a java.lang.Error for the VM.
674 *******************************************************************************/
676 #if defined(ENABLE_JAVAME_CLDC1_1)
677 static java_handle_t *exceptions_new_error(utf *message)
681 o = exceptions_new_class_utf(class_java_lang_Error, message);
688 /* exceptions_asm_new_abstractmethoderror **************************************
690 Generates a java.lang.AbstractMethodError for
691 asm_abstractmethoderror.
693 *******************************************************************************/
695 java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
700 /* create the stackframeinfo (XPC is equal to RA) */
702 stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra);
704 /* create the exception */
706 #if defined(ENABLE_JAVASE)
707 e = exceptions_new_abstractmethoderror();
709 e = exceptions_new_error(utf_java_lang_AbstractMethodError);
712 /* remove the stackframeinfo */
714 stacktrace_remove_stackframeinfo(&sfi);
720 /* exceptions_new_arraystoreexception ******************************************
722 Generates a java.lang.ArrayStoreException for the VM.
724 *******************************************************************************/
726 java_handle_t *exceptions_new_arraystoreexception(void)
730 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
736 /* exceptions_throw_abstractmethoderror ****************************************
738 Generates and throws a java.lang.AbstractMethodError for the VM.
740 *******************************************************************************/
742 void exceptions_throw_abstractmethoderror(void)
744 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
748 /* exceptions_throw_classcircularityerror **************************************
750 Generates and throws a java.lang.ClassCircularityError for the
754 c....the class in which the error was found
756 *******************************************************************************/
758 void exceptions_throw_classcircularityerror(classinfo *c)
760 exceptions_throw_utf_utf(utf_java_lang_ClassCircularityError, c->name);
764 /* exceptions_throw_classformaterror *******************************************
766 Generates and throws a java.lang.ClassFormatError for the VM.
769 c............the class in which the error was found
770 message......UTF-8 format string
772 *******************************************************************************/
774 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
781 /* calculate message length */
786 msglen += utf_bytes(c->name) + strlen(" (");
788 va_start(ap, message);
789 msglen += get_variable_message_length(message, ap);
793 msglen += strlen(")");
795 msglen += strlen("0");
797 /* allocate a buffer */
799 msg = MNEW(char, msglen);
801 /* print message into allocated buffer */
804 utf_copy_classname(msg, c->name);
808 va_start(ap, message);
809 vsprintf(msg + strlen(msg), message, ap);
815 u = utf_new_char(msg);
819 MFREE(msg, char, msglen);
821 /* throw exception */
823 exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
827 /* exceptions_throw_classnotfoundexception *************************************
829 Generates and throws a java.lang.ClassNotFoundException for the
833 name.........name of the class not found as a utf *
835 *******************************************************************************/
837 void exceptions_throw_classnotfoundexception(utf *name)
839 /* we use class here, as this one is rather frequent */
841 exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
845 /* exceptions_throw_noclassdeffounderror ***************************************
847 Generates and throws a java.lang.NoClassDefFoundError.
850 name.........name of the class not found as a utf *
852 *******************************************************************************/
854 void exceptions_throw_noclassdeffounderror(utf *name)
857 vm_abort("java.lang.NoClassDefFoundError: %s", name->text);
859 exceptions_throw_class_utf(class_java_lang_NoClassDefFoundError, name);
863 /* exceptions_throw_noclassdeffounderror_cause *********************************
865 Generates and throws a java.lang.NoClassDefFoundError with the
868 *******************************************************************************/
870 void exceptions_throw_noclassdeffounderror_cause(java_handle_t *cause)
872 exceptions_throw_utf_cause(utf_java_lang_NoClassDefFoundError, cause);
876 /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
878 Generates and throws a java.lang.NoClassDefFoundError with a
882 name.........name of the class not found as a utf *
884 *******************************************************************************/
886 void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
892 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
893 utf_bytes(name) + strlen(")") + strlen("0");
895 msg = MNEW(char, msglen);
897 utf_copy_classname(msg, c->name);
898 strcat(msg, " (wrong name: ");
899 utf_cat_classname(msg, name);
902 u = utf_new_char(msg);
904 MFREE(msg, char, msglen);
906 exceptions_throw_noclassdeffounderror(u);
910 /* exceptions_throw_exceptionininitializererror ********************************
912 Generates and throws a java.lang.ExceptionInInitializerError for
916 cause......cause exception object
918 *******************************************************************************/
920 void exceptions_throw_exceptionininitializererror(java_handle_t *cause)
922 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
927 /* exceptions_throw_incompatibleclasschangeerror *******************************
929 Generates and throws a java.lang.IncompatibleClassChangeError for
933 message......UTF-8 message format string
935 *******************************************************************************/
937 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
943 /* calculate exception message length */
945 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
947 /* allocate memory */
949 msg = MNEW(char, msglen);
951 utf_copy_classname(msg, c->name);
952 strcat(msg, message);
954 u = utf_new_char(msg);
958 MFREE(msg, char, msglen);
960 /* throw exception */
962 exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
966 /* exceptions_throw_instantiationerror *****************************************
968 Generates and throws a java.lang.InstantiationError for the VM.
970 *******************************************************************************/
972 void exceptions_throw_instantiationerror(classinfo *c)
974 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
978 /* exceptions_throw_internalerror **********************************************
980 Generates and throws a java.lang.InternalError for the VM.
983 message......UTF-8 message format string
985 *******************************************************************************/
987 void exceptions_throw_internalerror(const char *message, ...)
994 /* calculate exception message length */
996 va_start(ap, message);
997 msglen = get_variable_message_length(message, ap);
1000 /* allocate memory */
1002 msg = MNEW(char, msglen);
1004 /* generate message */
1006 va_start(ap, message);
1007 vsprintf(msg, message, ap);
1010 u = utf_new_char(msg);
1014 MFREE(msg, char, msglen);
1016 /* throw exception */
1018 exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
1022 /* exceptions_throw_linkageerror ***********************************************
1024 Generates and throws java.lang.LinkageError with an error message.
1027 message......UTF-8 message
1028 c............class related to the error. If this is != NULL
1029 the name of c is appended to the error message.
1031 *******************************************************************************/
1033 void exceptions_throw_linkageerror(const char *message, classinfo *c)
1039 /* calculate exception message length */
1041 msglen = strlen(message) + 1;
1044 msglen += utf_bytes(c->name);
1046 /* allocate memory */
1048 msg = MNEW(char, msglen);
1050 /* generate message */
1052 strcpy(msg,message);
1055 utf_cat_classname(msg, c->name);
1057 o = native_new_and_init_string(class_java_lang_LinkageError,
1058 javastring_new_from_utf_string(msg));
1062 MFREE(msg, char, msglen);
1067 exceptions_set_exception(o);
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_class_utf(class_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_class(class_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_class_utf(class_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);
1458 /* e = native_new_and_init(class_java_lang_ArrayStoreException); */
1462 /* exceptions_new_classcastexception *******************************************
1464 Generates a java.lang.ClassCastException for the JIT compiler.
1466 *******************************************************************************/
1468 java_handle_t *exceptions_new_classcastexception(java_handle_t *o)
1473 classname = o->vftbl->class->name;
1475 e = exceptions_new_class_utf(class_java_lang_ClassCastException, classname);
1481 /* exceptions_throw_clonenotsupportedexception *********************************
1483 Generates and throws a java.lang.CloneNotSupportedException for the
1486 *******************************************************************************/
1488 void exceptions_throw_clonenotsupportedexception(void)
1490 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1494 /* exceptions_throw_illegalaccessexception *************************************
1496 Generates and throws a java.lang.IllegalAccessException for the VM.
1498 *******************************************************************************/
1500 void exceptions_throw_illegalaccessexception(utf *message)
1502 exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
1506 /* exceptions_throw_illegalargumentexception ***********************************
1508 Generates and throws a java.lang.IllegalArgumentException for the
1511 *******************************************************************************/
1513 void exceptions_throw_illegalargumentexception(void)
1515 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1519 /* exceptions_throw_illegalmonitorstateexception *******************************
1521 Generates and throws a java.lang.IllegalMonitorStateException for
1524 *******************************************************************************/
1526 void exceptions_throw_illegalmonitorstateexception(void)
1528 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1532 /* exceptions_throw_instantiationexception *************************************
1534 Generates and throws a java.lang.InstantiationException for the VM.
1536 *******************************************************************************/
1538 void exceptions_throw_instantiationexception(classinfo *c)
1540 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1544 /* exceptions_throw_interruptedexception ***************************************
1546 Generates and throws a java.lang.InterruptedException for the VM.
1548 *******************************************************************************/
1550 void exceptions_throw_interruptedexception(void)
1552 exceptions_throw_utf(utf_java_lang_InterruptedException);
1556 /* exceptions_throw_invocationtargetexception **********************************
1558 Generates and throws a java.lang.reflect.InvocationTargetException
1562 cause......cause exception object
1564 *******************************************************************************/
1566 void exceptions_throw_invocationtargetexception(java_handle_t *cause)
1568 exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1573 /* exceptions_throw_negativearraysizeexception *********************************
1575 Generates and throws a java.lang.NegativeArraySizeException for the
1578 *******************************************************************************/
1580 void exceptions_throw_negativearraysizeexception(void)
1582 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1586 /* exceptions_new_nullpointerexception *****************************************
1588 Generates a java.lang.NullPointerException for the VM system.
1590 *******************************************************************************/
1592 java_handle_t *exceptions_new_nullpointerexception(void)
1596 o = exceptions_new_class(class_java_lang_NullPointerException);
1602 /* exceptions_throw_nullpointerexception ***************************************
1604 Generates a java.lang.NullPointerException for the VM system and
1605 throw it in the VM system.
1607 *******************************************************************************/
1609 void exceptions_throw_nullpointerexception(void)
1611 exceptions_throw_class(class_java_lang_NullPointerException);
1615 /* exceptions_throw_privilegedactionexception **********************************
1617 Generates and throws a java.security.PrivilegedActionException.
1619 *******************************************************************************/
1621 void exceptions_throw_privilegedactionexception(java_handle_t *exception)
1623 exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
1628 /* exceptions_throw_stringindexoutofboundsexception ****************************
1630 Generates and throws a java.lang.StringIndexOutOfBoundsException
1633 *******************************************************************************/
1635 void exceptions_throw_stringindexoutofboundsexception(void)
1637 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1641 /* exceptions_classnotfoundexception_to_noclassdeffounderror *******************
1643 Check the exception for a ClassNotFoundException. If it is one,
1644 convert it to a NoClassDefFoundError.
1646 *******************************************************************************/
1648 void exceptions_classnotfoundexception_to_noclassdeffounderror(void)
1651 java_handle_t *cause;
1652 java_lang_Throwable *object;
1653 java_lang_String *s;
1657 cause = exceptions_get_exception();
1659 /* convert ClassNotFoundException's to NoClassDefFoundError's */
1661 if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
1662 /* clear exception, because we are calling jit code again */
1664 exceptions_clear_exception();
1666 /* create new error */
1668 object = (java_lang_Throwable *) cause;
1669 LLNI_field_get_ref(object, detailMessage, s);
1671 o = exceptions_new_utf_javastring(utf_java_lang_NoClassDefFoundError,
1672 (java_handle_t *) s);
1674 /* we had an exception while creating the error */
1676 if (exceptions_get_exception())
1679 /* set new exception */
1681 exceptions_set_exception(o);
1686 /* exceptions_fillinstacktrace *************************************************
1688 Calls the fillInStackTrace-method of the currently thrown
1691 *******************************************************************************/
1693 java_handle_t *exceptions_fillinstacktrace(void)
1700 o = exceptions_get_and_clear_exception();
1704 /* resolve methodinfo pointer from exception object */
1706 #if defined(ENABLE_JAVASE)
1707 m = class_resolvemethod(o->vftbl->class,
1708 utf_fillInStackTrace,
1709 utf_void__java_lang_Throwable);
1710 #elif defined(ENABLE_JAVAME_CLDC1_1)
1711 m = class_resolvemethod(o->vftbl->class,
1712 utf_fillInStackTrace,
1715 #error IMPLEMENT ME!
1720 (void) vm_call_method(m, o);
1722 /* return exception object */
1728 /* exceptions_handle_exception *************************************************
1730 Try to find an exception handler for the given exception and return it.
1731 If no handler is found, exit the monitor of the method (if any)
1735 xptr.........the exception object
1736 xpc..........PC of where the exception was thrown
1737 pv...........Procedure Value of the current method
1738 sp...........current stack pointer
1741 the address of the first matching exception handler, or
1742 NULL if no handler was found
1744 *******************************************************************************/
1746 #if defined(ENABLE_JIT)
1747 u1 *exceptions_handle_exception(java_object_t *xptr, u1 *xpc, u1 *pv, u1 *sp)
1752 dseg_exception_entry *ex;
1753 s4 exceptiontablelength;
1755 classref_or_classinfo cr;
1757 #if defined(ENABLE_THREADS)
1762 /* Addresses are 31 bit integers */
1763 # define ADDR_MASK(x) (u1 *)((u4)(x) & 0x7FFFFFFF)
1765 # define ADDR_MASK(x) (x)
1768 xpc = ADDR_MASK(xpc);
1770 /* get info from the method header */
1772 code = *((codeinfo **) (pv + CodeinfoPointer));
1773 issync = *((s4 *) (pv + IsSync));
1774 ex = (dseg_exception_entry *) (pv + ExTableStart);
1775 exceptiontablelength = *((s4 *) (pv + ExTableSize));
1777 /* Get the methodinfo pointer from the codeinfo pointer. For
1778 asm_vm_call_method the codeinfo pointer is NULL. */
1780 m = (code == NULL) ? NULL : code->m;
1782 #if !defined(NDEBUG)
1783 /* print exception trace */
1785 if (opt_verbose || opt_verbosecall || opt_TraceExceptions)
1786 builtin_trace_exception(xptr, m, xpc, 1);
1789 #if defined(ENABLE_VMLOG)
1790 vmlog_cacao_throw(xptr);
1793 for (i = 0; i < exceptiontablelength; i++) {
1794 /* ATTENTION: keep this here, as we need to decrement the
1795 pointer before the loop executes! */
1799 /* If the start and end PC is NULL, this means we have the
1800 special case of asm_vm_call_method. So, just return the
1801 proper exception handler. */
1803 if ((ex->startpc == NULL) && (ex->endpc == NULL))
1804 return (u1 *) (ptrint) &asm_vm_call_method_exception_handler;
1806 /* is the xpc is the current catch range */
1808 if ((ADDR_MASK(ex->startpc) <= xpc) && (xpc < ADDR_MASK(ex->endpc))) {
1811 /* NULL catches everything */
1813 if (cr.any == NULL) {
1814 #if !defined(NDEBUG)
1815 /* Print stacktrace of exception when caught. */
1817 #if defined(ENABLE_VMLOG)
1818 vmlog_cacao_catch(xptr);
1821 if (opt_TraceExceptions) {
1822 exceptions_print_exception(xptr);
1823 stacktrace_print_trace(xptr);
1827 return ex->handlerpc;
1830 /* resolve or load/link the exception class */
1832 if (IS_CLASSREF(cr)) {
1833 /* The exception class reference is unresolved. */
1834 /* We have to do _eager_ resolving here. While the class of */
1835 /* the exception object is guaranteed to be loaded, it may */
1836 /* well have been loaded by a different loader than the */
1837 /* defining loader of m's class, which is the one we must */
1838 /* use to resolve the catch class. Thus lazy resolving */
1839 /* might fail, even if the result of the resolution would */
1840 /* be an already loaded class. */
1842 c = resolve_classref_eager(cr.ref);
1845 /* Exception resolving the exception class, argh! */
1849 /* Ok, we resolved it. Enter it in the table, so we don't */
1850 /* have to do this again. */
1851 /* XXX this write should be atomic. Is it? */
1853 ex->catchtype.cls = c;
1857 /* XXX I don't think this case can ever happen. -Edwin */
1858 if (!(c->state & CLASS_LOADED))
1859 /* use the methods' classloader */
1860 if (!load_class_from_classloader(c->name,
1861 m->class->classloader))
1864 /* XXX I think, if it is not linked, we can be sure that */
1865 /* the exception object is no (indirect) instance of it, no? */
1867 if (!(c->state & CLASS_LINKED))
1872 /* is the thrown exception an instance of the catch class? */
1874 if (builtin_instanceof(xptr, c)) {
1875 #if !defined(NDEBUG)
1876 /* Print stacktrace of exception when caught. */
1878 #if defined(ENABLE_VMLOG)
1879 vmlog_cacao_catch(xptr);
1882 if (opt_TraceExceptions) {
1883 exceptions_print_exception(xptr);
1884 stacktrace_print_trace(xptr);
1888 return ex->handlerpc;
1893 #if defined(ENABLE_THREADS)
1894 /* is this method synchronized? */
1897 /* get synchronization object */
1899 # if (defined(__MIPS__) && (SIZEOF_VOID_P == 4)) || defined(__I386__) || defined(__S390__) || defined(__POWERPC__)
1900 /* XXX change this if we ever want to use 4-byte stackslots */
1901 o = *((java_object_t **) (sp + issync - 8));
1903 o = *((java_object_t **) (sp + issync - SIZEOF_VOID_P));
1908 lock_monitor_exit(o);
1912 /* none of the exceptions catch this one */
1914 #if defined(ENABLE_VMLOG)
1915 vmlog_cacao_unwnd_method(m);
1920 #endif /* defined(ENABLE_JIT) */
1923 /* exceptions_print_exception **************************************************
1925 Prints an exception, the detail message and the cause, if
1926 available, with CACAO internal functions to stdout.
1928 *******************************************************************************/
1930 void exceptions_print_exception(java_handle_t *xptr)
1932 java_lang_Throwable *t;
1933 #if defined(ENABLE_JAVASE)
1934 java_lang_Throwable *cause;
1936 java_lang_String *s;
1940 t = (java_lang_Throwable *) xptr;
1947 #if defined(ENABLE_JAVASE)
1948 LLNI_field_get_ref(t, cause, cause);
1951 /* print the root exception */
1953 LLNI_class_get(t, c);
1954 utf_display_printable_ascii_classname(c->name);
1956 LLNI_field_get_ref(t, detailMessage, s);
1959 u = javastring_toutf((java_handle_t *) s, false);
1962 utf_display_printable_ascii(u);
1967 #if defined(ENABLE_JAVASE)
1968 /* print the cause if available */
1970 if ((cause != NULL) && (cause != t)) {
1971 printf("Caused by: ");
1973 LLNI_class_get(cause, c);
1974 utf_display_printable_ascii_classname(c->name);
1976 LLNI_field_get_ref(cause, detailMessage, s);
1979 u = javastring_toutf((java_handle_t *) s, false);
1982 utf_display_printable_ascii(u);
1991 /* exceptions_print_current_exception ******************************************
1993 Prints the current pending exception, the detail message and the
1994 cause, if available, with CACAO internal functions to stdout.
1996 *******************************************************************************/
1998 void exceptions_print_current_exception(void)
2002 o = exceptions_get_exception();
2004 exceptions_print_exception(o);
2008 /* exceptions_print_stacktrace *************************************************
2010 Prints a pending exception with Throwable.printStackTrace(). If
2011 there happens an exception during printStackTrace(), we print the
2012 thrown exception and the original one.
2014 NOTE: This function calls Java code.
2016 *******************************************************************************/
2018 void exceptions_print_stacktrace(void)
2020 java_handle_t *oxptr;
2021 java_handle_t *xptr;
2025 /* get original exception */
2027 oxptr = exceptions_get_and_clear_exception();
2030 vm_abort("exceptions_print_stacktrace: no exception thrown");
2032 /* clear exception, because we are calling jit code again */
2034 c = oxptr->vftbl->class;
2036 /* find the printStackTrace() method */
2038 m = class_resolveclassmethod(c,
2039 utf_printStackTrace,
2041 class_java_lang_Object,
2045 vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
2047 /* print compatibility message */
2049 fprintf(stderr, "Exception in thread \"main\" ");
2051 /* print the stacktrace */
2053 (void) vm_call_method(m, oxptr);
2055 /* This normally means, we are EXTREMLY out of memory or
2056 have a serious problem while printStackTrace. But may
2057 be another exception, so print it. */
2059 xptr = exceptions_get_exception();
2062 fprintf(stderr, "Exception while printStackTrace(): ");
2064 /* now print original exception */
2066 exceptions_print_exception(xptr);
2067 stacktrace_print_trace(xptr);
2069 /* now print original exception */
2071 fprintf(stderr, "Original exception was: ");
2072 exceptions_print_exception(oxptr);
2073 stacktrace_print_trace(oxptr);
2081 * These are local overrides for various environment variables in Emacs.
2082 * Please do not remove this and leave it at the end of the file, where
2083 * Emacs will automagically detect them.
2084 * ---------------------------------------------------------------------
2087 * indent-tabs-mode: t
2091 * vim:noexpandtab:sw=4:ts=4: