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
25 $Id: exceptions.c 8283 2007-08-09 15:10:05Z twisti $
43 #include "mm/memory.h"
45 #include "native/jni.h"
46 #include "native/native.h"
48 #include "native/include/java_lang_String.h"
49 #include "native/include/java_lang_Throwable.h"
51 #include "threads/lock-common.h"
52 #include "threads/threads-common.h"
54 #include "toolbox/util.h"
56 #include "vm/builtin.h"
57 #include "vm/exceptions.h"
58 #include "vm/global.h"
59 #include "vm/stringlocal.h"
62 #include "vm/jit/asmpart.h"
63 #include "vm/jit/jit.h"
64 #include "vm/jit/methodheader.h"
65 #include "vm/jit/patcher-common.h"
66 #include "vm/jit/stacktrace.h"
68 #include "vmcore/class.h"
69 #include "vmcore/loader.h"
70 #include "vmcore/method.h"
71 #include "vmcore/options.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_objectheader *_no_threads_exceptionptr = NULL;
85 /* init_system_exceptions ******************************************************
87 Load and link exceptions used in the system.
89 *******************************************************************************/
91 bool 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 = getpagesize();
104 (void) memory_mmap_anon(NULL, pagesize, PROT_NONE, MAP_PRIVATE | MAP_FIXED);
107 /* check if we get into trouble with our hardware-exceptions */
109 if (OFFSET(java_bytearray, data) <= EXCEPTION_HARDWARE_LARGEST)
110 vm_abort("signal_init: array-data offset is less or equal the maximum hardware-exception displacement: %d <= %d", OFFSET(java_bytearray, data), EXCEPTION_HARDWARE_LARGEST);
112 /* java/lang/Throwable */
114 if (!(class_java_lang_Throwable =
115 load_class_bootstrap(utf_java_lang_Throwable)) ||
116 !link_class(class_java_lang_Throwable))
119 /* java/lang/Error */
121 if (!(class_java_lang_Error = load_class_bootstrap(utf_java_lang_Error)) ||
122 !link_class(class_java_lang_Error))
125 #if defined(ENABLE_JAVASE)
126 /* java/lang/LinkageError */
128 if (!(class_java_lang_LinkageError =
129 load_class_bootstrap(utf_java_lang_LinkageError)) ||
130 !link_class(class_java_lang_LinkageError))
134 /* java/lang/NoClassDefFoundError */
136 if (!(class_java_lang_NoClassDefFoundError =
137 load_class_bootstrap(utf_java_lang_NoClassDefFoundError)) ||
138 !link_class(class_java_lang_NoClassDefFoundError))
141 /* java/lang/OutOfMemoryError */
143 if (!(class_java_lang_OutOfMemoryError =
144 load_class_bootstrap(utf_java_lang_OutOfMemoryError)) ||
145 !link_class(class_java_lang_OutOfMemoryError))
148 /* java/lang/VirtualMachineError */
150 if (!(class_java_lang_VirtualMachineError =
151 load_class_bootstrap(utf_java_lang_VirtualMachineError)) ||
152 !link_class(class_java_lang_VirtualMachineError))
156 /* java/lang/Exception */
158 if (!(class_java_lang_Exception =
159 load_class_bootstrap(utf_java_lang_Exception)) ||
160 !link_class(class_java_lang_Exception))
163 /* java/lang/ClassCastException */
165 if (!(class_java_lang_ClassCastException =
166 load_class_bootstrap(utf_java_lang_ClassCastException)) ||
167 !link_class(class_java_lang_ClassCastException))
170 /* java/lang/ClassNotFoundException */
172 if (!(class_java_lang_ClassNotFoundException =
173 load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
174 !link_class(class_java_lang_ClassNotFoundException))
177 /* java/lang/NullPointerException */
179 if (!(class_java_lang_NullPointerException =
180 load_class_bootstrap(utf_java_lang_NullPointerException)) ||
181 !link_class(class_java_lang_NullPointerException))
185 #if defined(WITH_CLASSPATH_GNU)
186 /* java/lang/VMThrowable */
188 if (!(class_java_lang_VMThrowable =
189 load_class_bootstrap(utf_java_lang_VMThrowable)) ||
190 !link_class(class_java_lang_VMThrowable))
198 /* exceptions_get_exception ****************************************************
200 Returns the current exception pointer of the current thread.
202 *******************************************************************************/
204 java_objectheader *exceptions_get_exception(void)
206 /* return the exception */
208 return *exceptionptr;
212 /* exceptions_set_exception ****************************************************
214 Sets the exception pointer of the current thread.
216 *******************************************************************************/
218 void exceptions_set_exception(java_objectheader *o)
220 /* set the exception */
226 /* exceptions_clear_exception **************************************************
228 Clears the current exception pointer of the current thread.
230 *******************************************************************************/
232 void exceptions_clear_exception(void)
234 exceptions_set_exception(NULL);
238 /* exceptions_get_and_clear_exception ******************************************
240 Gets the exception pointer of the current thread and clears it.
241 This function may return NULL.
243 *******************************************************************************/
245 java_objectheader *exceptions_get_and_clear_exception(void)
247 java_objectheader *o;
249 /* get the exception */
251 o = exceptions_get_exception();
253 /* and clear the exception */
255 exceptions_clear_exception();
257 /* return the exception */
263 /* exceptions_new_class ********************************************************
265 Creates an exception object from the given class and initalizes it.
268 class....class pointer
270 *******************************************************************************/
272 static java_objectheader *exceptions_new_class(classinfo *c)
274 java_objectheader *o;
276 o = native_new_and_init(c);
279 return exceptions_get_exception();
285 /* exceptions_new_utf **********************************************************
287 Creates an exception object with the given name and initalizes it.
290 classname....class name in UTF-8
292 *******************************************************************************/
294 static java_objectheader *exceptions_new_utf(utf *classname)
297 java_objectheader *o;
299 c = load_class_bootstrap(classname);
302 return exceptions_get_exception();
304 o = exceptions_new_class(c);
310 /* exceptions_throw_class ******************************************************
312 Creates an exception object from the given class, initalizes and
316 class....class pointer
318 *******************************************************************************/
320 static void exceptions_throw_class(classinfo *c)
322 java_objectheader *o;
324 o = exceptions_new_class(c);
329 exceptions_set_exception(o);
333 /* exceptions_throw_utf ********************************************************
335 Creates an exception object with the given name, initalizes and
339 classname....class name in UTF-8
341 *******************************************************************************/
343 static void exceptions_throw_utf(utf *classname)
347 c = load_class_bootstrap(classname);
352 exceptions_throw_class(c);
356 /* exceptions_throw_utf_throwable **********************************************
358 Creates an exception object with the given name and initalizes it
359 with the given java/lang/Throwable exception.
362 classname....class name in UTF-8
363 cause........the given Throwable
365 *******************************************************************************/
367 static void exceptions_throw_utf_throwable(utf *classname,
368 java_objectheader *cause)
371 java_objectheader *o;
373 java_lang_Throwable *object;
375 object = (java_lang_Throwable *) cause;
377 c = load_class_bootstrap(classname);
389 /* call initializer */
391 m = class_resolveclassmethod(c,
393 utf_java_lang_Throwable__void,
400 (void) vm_call_method(m, o, cause);
402 exceptions_set_exception(o);
406 /* exceptions_throw_utf_exception **********************************************
408 Creates an exception object with the given name and initalizes it
409 with the given java/lang/Exception exception.
412 classname....class name in UTF-8
413 exception....the given Exception
415 *******************************************************************************/
417 static void exceptions_throw_utf_exception(utf *classname,
418 java_objectheader *exception)
421 java_objectheader *o;
424 c = load_class_bootstrap(classname);
436 /* call initializer */
438 m = class_resolveclassmethod(c,
440 utf_java_lang_Exception__V,
447 (void) vm_call_method(m, o, exception);
449 exceptions_set_exception(o);
453 /* exceptions_throw_utf_cause **************************************************
455 Creates an exception object with the given name and initalizes it
456 with the given java/lang/Throwable exception with initCause.
459 classname....class name in UTF-8
460 cause........the given Throwable
462 *******************************************************************************/
464 static void exceptions_throw_utf_cause(utf *classname, java_objectheader *cause)
467 java_objectheader *o;
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 (void) vm_call_method(m, o, object->detailMessage);
500 m = class_resolveclassmethod(c,
502 utf_java_lang_Throwable__java_lang_Throwable,
509 (void) vm_call_method(m, o, cause);
511 exceptions_set_exception(o);
515 /* exceptions_new_utf_javastring ***********************************************
517 Creates an exception object with the given name and initalizes it
518 with the given java/lang/String message.
521 classname....class name in UTF-8
522 message......the message as a java.lang.String
525 an exception pointer (in any case -- either it is the newly created
526 exception, or an exception thrown while trying to create it).
528 *******************************************************************************/
530 static java_objectheader *exceptions_new_utf_javastring(utf *classname,
531 java_objectheader *message)
533 java_objectheader *o;
536 c = load_class_bootstrap(classname);
539 return exceptions_get_exception();
541 o = native_new_and_init_string(c, message);
544 return exceptions_get_exception();
550 /* exceptions_new_class_utf ****************************************************
552 Creates an exception object of the given class and initalizes it.
555 c..........class pointer
556 message....the message as UTF-8 string
558 *******************************************************************************/
560 static java_objectheader *exceptions_new_class_utf(classinfo *c, utf *message)
562 java_objectheader *o;
563 java_objectheader *s;
565 s = javastring_new(message);
568 return exceptions_get_exception();
570 o = native_new_and_init_string(c, s);
573 return exceptions_get_exception();
579 /* exceptions_new_utf_utf ******************************************************
581 Creates an exception object with the given name and initalizes it
582 with the given utf message.
585 classname....class name in UTF-8
586 message......the message as an utf *
589 an exception pointer (in any case -- either it is the newly created
590 exception, or an exception thrown while trying to create it).
592 *******************************************************************************/
594 static java_objectheader *exceptions_new_utf_utf(utf *classname, utf *message)
597 java_objectheader *o;
599 c = load_class_bootstrap(classname);
602 return exceptions_get_exception();
604 o = exceptions_new_class_utf(c, message);
610 /* exceptions_throw_class_utf **************************************************
612 Creates an exception object of the given class, initalizes and
613 throws it with the given utf message.
616 c..........class pointer
617 message....the message as an UTF-8
619 *******************************************************************************/
621 static void exceptions_throw_class_utf(classinfo *c, utf *message)
623 java_objectheader *o;
625 o = exceptions_new_class_utf(c, message);
627 exceptions_set_exception(o);
631 /* exceptions_throw_utf_utf ****************************************************
633 Creates an exception object with the given name, initalizes and
634 throws it with the given utf message.
637 classname....class name in UTF-8
638 message......the message as an utf *
640 *******************************************************************************/
642 static void exceptions_throw_utf_utf(utf *classname, utf *message)
644 java_objectheader *o;
646 o = exceptions_new_utf_utf(classname, message);
648 exceptions_set_exception(o);
652 /* exceptions_new_abstractmethoderror ****************************************
654 Generates a java.lang.AbstractMethodError for the VM.
656 *******************************************************************************/
658 java_objectheader *exceptions_new_abstractmethoderror(void)
660 java_objectheader *o;
662 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
668 /* exceptions_new_error ********************************************************
670 Generates a java.lang.Error for the VM.
672 *******************************************************************************/
674 #if defined(ENABLE_JAVAME_CLDC1_1)
675 static java_objectheader *exceptions_new_error(utf *message)
677 java_objectheader *o;
679 o = exceptions_new_class_utf(class_java_lang_Error, message);
686 /* exceptions_asm_new_abstractmethoderror **************************************
688 Generates a java.lang.AbstractMethodError for
689 asm_abstractmethoderror.
691 *******************************************************************************/
693 java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
696 java_objectheader *e;
698 /* create the stackframeinfo (XPC is equal to RA) */
700 stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra);
702 /* create the exception */
704 #if defined(ENABLE_JAVASE)
705 e = exceptions_new_abstractmethoderror();
707 e = exceptions_new_error(utf_java_lang_AbstractMethodError);
710 /* remove the stackframeinfo */
712 stacktrace_remove_stackframeinfo(&sfi);
718 /* exceptions_new_arraystoreexception ******************************************
720 Generates a java.lang.ArrayStoreException for the VM.
722 *******************************************************************************/
724 java_objectheader *exceptions_new_arraystoreexception(void)
726 java_objectheader *o;
728 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
734 /* exceptions_throw_abstractmethoderror ****************************************
736 Generates and throws a java.lang.AbstractMethodError for the VM.
738 *******************************************************************************/
740 void exceptions_throw_abstractmethoderror(void)
742 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
746 /* exceptions_throw_classcircularityerror **************************************
748 Generates and throws a java.lang.ClassCircularityError for the
752 c....the class in which the error was found
754 *******************************************************************************/
756 void exceptions_throw_classcircularityerror(classinfo *c)
758 exceptions_throw_utf_utf(utf_java_lang_ClassCircularityError, c->name);
762 /* exceptions_throw_classformaterror *******************************************
764 Generates and throws a java.lang.ClassFormatError for the VM.
767 c............the class in which the error was found
768 message......UTF-8 format string
770 *******************************************************************************/
772 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
779 /* calculate message length */
784 msglen += utf_bytes(c->name) + strlen(" (");
786 va_start(ap, message);
787 msglen += get_variable_message_length(message, ap);
791 msglen += strlen(")");
793 msglen += strlen("0");
795 /* allocate a buffer */
797 msg = MNEW(char, msglen);
799 /* print message into allocated buffer */
802 utf_copy_classname(msg, c->name);
806 va_start(ap, message);
807 vsprintf(msg + strlen(msg), message, ap);
813 u = utf_new_char(msg);
817 MFREE(msg, char, msglen);
819 /* throw exception */
821 exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
825 /* exceptions_throw_classnotfoundexception *************************************
827 Generates and throws a java.lang.ClassNotFoundException for the
831 name.........name of the class not found as a utf *
833 *******************************************************************************/
835 void exceptions_throw_classnotfoundexception(utf *name)
837 /* we use class here, as this one is rather frequent */
839 exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
843 /* exceptions_throw_noclassdeffounderror ***************************************
845 Generates and throws a java.lang.NoClassDefFoundError.
848 name.........name of the class not found as a utf *
850 *******************************************************************************/
852 void exceptions_throw_noclassdeffounderror(utf *name)
855 vm_abort("java.lang.NoClassDefFoundError: %s", name->text);
857 exceptions_throw_class_utf(class_java_lang_NoClassDefFoundError, name);
861 /* exceptions_throw_noclassdeffounderror_cause *********************************
863 Generates and throws a java.lang.NoClassDefFoundError with the
866 *******************************************************************************/
868 void exceptions_throw_noclassdeffounderror_cause(java_objectheader *cause)
870 exceptions_throw_utf_cause(utf_java_lang_NoClassDefFoundError, cause);
874 /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
876 Generates and throws a java.lang.NoClassDefFoundError with a
880 name.........name of the class not found as a utf *
882 *******************************************************************************/
884 void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
890 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
891 utf_bytes(name) + strlen(")") + strlen("0");
893 msg = MNEW(char, msglen);
895 utf_copy_classname(msg, c->name);
896 strcat(msg, " (wrong name: ");
897 utf_cat_classname(msg, name);
900 u = utf_new_char(msg);
902 MFREE(msg, char, msglen);
904 exceptions_throw_noclassdeffounderror(u);
908 /* exceptions_throw_exceptionininitializererror ********************************
910 Generates and throws a java.lang.ExceptionInInitializerError for
914 cause......cause exception object
916 *******************************************************************************/
918 void exceptions_throw_exceptionininitializererror(java_objectheader *cause)
920 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
925 /* exceptions_throw_incompatibleclasschangeerror *******************************
927 Generates and throws a java.lang.IncompatibleClassChangeError for
931 message......UTF-8 message format string
933 *******************************************************************************/
935 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
941 /* calculate exception message length */
943 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
945 /* allocate memory */
947 msg = MNEW(char, msglen);
949 utf_copy_classname(msg, c->name);
950 strcat(msg, message);
952 u = utf_new_char(msg);
956 MFREE(msg, char, msglen);
958 /* throw exception */
960 exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
964 /* exceptions_throw_instantiationerror *****************************************
966 Generates and throws a java.lang.InstantiationError for the VM.
968 *******************************************************************************/
970 void exceptions_throw_instantiationerror(classinfo *c)
972 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
976 /* exceptions_throw_internalerror **********************************************
978 Generates and throws a java.lang.InternalError for the VM.
981 message......UTF-8 message format string
983 *******************************************************************************/
985 void exceptions_throw_internalerror(const char *message, ...)
992 /* calculate exception message length */
994 va_start(ap, message);
995 msglen = get_variable_message_length(message, ap);
998 /* allocate memory */
1000 msg = MNEW(char, msglen);
1002 /* generate message */
1004 va_start(ap, message);
1005 vsprintf(msg, message, ap);
1008 u = utf_new_char(msg);
1012 MFREE(msg, char, msglen);
1014 /* throw exception */
1016 exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
1020 /* exceptions_throw_linkageerror ***********************************************
1022 Generates and throws java.lang.LinkageError with an error message.
1025 message......UTF-8 message
1026 c............class related to the error. If this is != NULL
1027 the name of c is appended to the error message.
1029 *******************************************************************************/
1031 void exceptions_throw_linkageerror(const char *message, classinfo *c)
1033 java_objectheader *o;
1037 /* calculate exception message length */
1039 msglen = strlen(message) + 1;
1042 msglen += utf_bytes(c->name);
1044 /* allocate memory */
1046 msg = MNEW(char, msglen);
1048 /* generate message */
1050 strcpy(msg,message);
1053 utf_cat_classname(msg, c->name);
1055 o = native_new_and_init_string(class_java_lang_LinkageError,
1056 javastring_new_from_utf_string(msg));
1060 MFREE(msg, char, msglen);
1065 exceptions_set_exception(o);
1069 /* exceptions_throw_nosuchfielderror *******************************************
1071 Generates and throws a java.lang.NoSuchFieldError with an error
1075 c............class in which the field was not found
1076 name.........name of the field
1078 *******************************************************************************/
1080 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
1086 /* calculate exception message length */
1088 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
1090 /* allocate memory */
1092 msg = MNEW(char, msglen);
1094 /* generate message */
1096 utf_copy_classname(msg, c->name);
1100 u = utf_new_char(msg);
1104 MFREE(msg, char, msglen);
1106 exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
1110 /* exceptions_throw_nosuchmethoderror ******************************************
1112 Generates and throws a java.lang.NoSuchMethodError with an error
1116 c............class in which the method was not found
1117 name.........name of the method
1118 desc.........descriptor of the method
1120 *******************************************************************************/
1122 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
1128 /* calculate exception message length */
1130 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
1131 utf_bytes(desc) + strlen("0");
1133 /* allocate memory */
1135 msg = MNEW(char, msglen);
1137 /* generate message */
1139 utf_copy_classname(msg, c->name);
1144 u = utf_new_char(msg);
1148 MFREE(msg, char, msglen);
1150 #if defined(ENABLE_JAVASE)
1151 exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
1153 exceptions_throw_class_utf(class_java_lang_Error, u);
1158 /* exceptions_throw_outofmemoryerror *******************************************
1160 Generates and throws an java.lang.OutOfMemoryError for the VM.
1162 *******************************************************************************/
1164 void exceptions_throw_outofmemoryerror(void)
1166 exceptions_throw_class(class_java_lang_OutOfMemoryError);
1170 /* exceptions_throw_unsatisfiedlinkerror ***************************************
1172 Generates and throws a java.lang.UnsatisfiedLinkError for the
1176 name......UTF-8 name string
1178 *******************************************************************************/
1180 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1182 #if defined(ENABLE_JAVASE)
1183 exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1185 exceptions_throw_class_utf(class_java_lang_Error, name);
1190 /* exceptions_throw_unsupportedclassversionerror *******************************
1192 Generates and throws a java.lang.UnsupportedClassVersionError for
1196 c............class in which the method was not found
1197 message......UTF-8 format string
1199 *******************************************************************************/
1201 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1207 /* calculate exception message length */
1210 utf_bytes(c->name) +
1211 strlen(" (Unsupported major.minor version 00.0)") +
1214 /* allocate memory */
1216 msg = MNEW(char, msglen);
1218 /* generate message */
1220 utf_copy_classname(msg, c->name);
1221 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1224 u = utf_new_char(msg);
1228 MFREE(msg, char, msglen);
1230 /* throw exception */
1232 exceptions_throw_utf_utf(utf_java_lang_UnsupportedClassVersionError, u);
1236 /* exceptions_throw_verifyerror ************************************************
1238 Generates and throws a java.lang.VerifyError for the JIT compiler.
1241 m............method in which the error was found
1242 message......UTF-8 format string
1244 *******************************************************************************/
1246 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1253 /* calculate exception message length */
1259 strlen("(class: ") + utf_bytes(m->class->name) +
1260 strlen(", method: ") + utf_bytes(m->name) +
1261 strlen(" signature: ") + utf_bytes(m->descriptor) +
1262 strlen(") ") + strlen("0");
1264 va_start(ap, message);
1265 msglen += get_variable_message_length(message, ap);
1268 /* allocate memory */
1270 msg = MNEW(char, msglen);
1272 /* generate message */
1275 strcpy(msg, "(class: ");
1276 utf_cat_classname(msg, m->class->name);
1277 strcat(msg, ", method: ");
1278 utf_cat(msg, m->name);
1279 strcat(msg, " signature: ");
1280 utf_cat(msg, m->descriptor);
1284 va_start(ap, message);
1285 vsprintf(msg + strlen(msg), message, ap);
1288 u = utf_new_char(msg);
1292 MFREE(msg, char, msglen);
1294 /* throw exception */
1296 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1300 /* exceptions_throw_verifyerror_for_stack **************************************
1302 throws a java.lang.VerifyError for an invalid stack slot type
1305 m............method in which the error was found
1306 type.........the expected type
1309 an exception pointer (in any case -- either it is the newly created
1310 exception, or an exception thrown while trying to create it).
1312 *******************************************************************************/
1314 void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
1321 /* calculate exception message length */
1326 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1327 strlen(", method: ") + utf_bytes(m->name) +
1328 strlen(" signature: ") + utf_bytes(m->descriptor) +
1329 strlen(") Expecting to find longest-------typename on stack")
1332 /* allocate memory */
1334 msg = MNEW(char, msglen);
1336 /* generate message */
1339 strcpy(msg, "(class: ");
1340 utf_cat_classname(msg, m->class->name);
1341 strcat(msg, ", method: ");
1342 utf_cat(msg, m->name);
1343 strcat(msg, " signature: ");
1344 utf_cat(msg, m->descriptor);
1351 strcat(msg, "Expecting to find ");
1354 case TYPE_INT: typename = "integer"; break;
1355 case TYPE_LNG: typename = "long"; break;
1356 case TYPE_FLT: typename = "float"; break;
1357 case TYPE_DBL: typename = "double"; break;
1358 case TYPE_ADR: typename = "object/array"; break;
1359 case TYPE_RET: typename = "returnAddress"; break;
1360 default: typename = "<INVALID>"; assert(0); break;
1363 strcat(msg, typename);
1364 strcat(msg, " on stack");
1366 u = utf_new_char(msg);
1370 MFREE(msg, char, msglen);
1372 /* throw exception */
1374 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1378 /* exceptions_new_arithmeticexception ******************************************
1380 Generates a java.lang.ArithmeticException for the JIT compiler.
1382 *******************************************************************************/
1384 java_objectheader *exceptions_new_arithmeticexception(void)
1386 java_objectheader *o;
1388 o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
1389 utf_division_by_zero);
1395 /* exceptions_new_arrayindexoutofboundsexception *******************************
1397 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1400 *******************************************************************************/
1402 java_objectheader *exceptions_new_arrayindexoutofboundsexception(s4 index)
1404 java_objectheader *o;
1406 java_objectheader *s;
1408 /* convert the index into a String, like Sun does */
1410 m = class_resolveclassmethod(class_java_lang_String,
1411 utf_new_char("valueOf"),
1412 utf_new_char("(I)Ljava/lang/String;"),
1413 class_java_lang_Object,
1417 return exceptions_get_exception();
1419 s = vm_call_method(m, NULL, index);
1422 return exceptions_get_exception();
1424 o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1428 return exceptions_get_exception();
1434 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1436 Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1439 *******************************************************************************/
1441 void exceptions_throw_arrayindexoutofboundsexception(void)
1443 exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1447 /* exceptions_throw_arraystoreexception ****************************************
1449 Generates and throws a java.lang.ArrayStoreException for the VM.
1451 *******************************************************************************/
1453 void exceptions_throw_arraystoreexception(void)
1455 exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1456 /* e = native_new_and_init(class_java_lang_ArrayStoreException); */
1460 /* exceptions_new_classcastexception *******************************************
1462 Generates a java.lang.ClassCastException for the JIT compiler.
1464 *******************************************************************************/
1466 java_objectheader *exceptions_new_classcastexception(java_objectheader *o)
1468 java_objectheader *e;
1471 classname = o->vftbl->class->name;
1473 e = exceptions_new_class_utf(class_java_lang_ClassCastException, classname);
1479 /* exceptions_throw_clonenotsupportedexception *********************************
1481 Generates and throws a java.lang.CloneNotSupportedException for the
1484 *******************************************************************************/
1486 void exceptions_throw_clonenotsupportedexception(void)
1488 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1492 /* exceptions_throw_illegalaccessexception *************************************
1494 Generates and throws a java.lang.IllegalAccessException for the VM.
1496 *******************************************************************************/
1498 void exceptions_throw_illegalaccessexception(utf *message)
1500 exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
1504 /* exceptions_throw_illegalargumentexception ***********************************
1506 Generates and throws a java.lang.IllegalArgumentException for the
1509 *******************************************************************************/
1511 void exceptions_throw_illegalargumentexception(void)
1513 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1517 /* exceptions_throw_illegalmonitorstateexception *******************************
1519 Generates and throws a java.lang.IllegalMonitorStateException for
1522 *******************************************************************************/
1524 void exceptions_throw_illegalmonitorstateexception(void)
1526 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1530 /* exceptions_throw_instantiationexception *************************************
1532 Generates and throws a java.lang.InstantiationException for the VM.
1534 *******************************************************************************/
1536 void exceptions_throw_instantiationexception(classinfo *c)
1538 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1542 /* exceptions_throw_interruptedexception ***************************************
1544 Generates and throws a java.lang.InterruptedException for the VM.
1546 *******************************************************************************/
1548 void exceptions_throw_interruptedexception(void)
1550 exceptions_throw_utf(utf_java_lang_InterruptedException);
1554 /* exceptions_throw_invocationtargetexception **********************************
1556 Generates and throws a java.lang.reflect.InvocationTargetException
1560 cause......cause exception object
1562 *******************************************************************************/
1564 void exceptions_throw_invocationtargetexception(java_objectheader *cause)
1566 exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1571 /* exceptions_throw_negativearraysizeexception *********************************
1573 Generates and throws a java.lang.NegativeArraySizeException for the
1576 *******************************************************************************/
1578 void exceptions_throw_negativearraysizeexception(void)
1580 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1584 /* exceptions_new_nullpointerexception *****************************************
1586 Generates a java.lang.NullPointerException for the VM system.
1588 *******************************************************************************/
1590 java_objectheader *exceptions_new_nullpointerexception(void)
1592 java_objectheader *o;
1594 o = exceptions_new_class(class_java_lang_NullPointerException);
1600 /* exceptions_throw_nullpointerexception ***************************************
1602 Generates a java.lang.NullPointerException for the VM system and
1603 throw it in the VM system.
1605 *******************************************************************************/
1607 void exceptions_throw_nullpointerexception(void)
1609 exceptions_throw_class(class_java_lang_NullPointerException);
1613 /* exceptions_throw_privilegedactionexception **********************************
1615 Generates and throws a java.security.PrivilegedActionException.
1617 *******************************************************************************/
1619 void exceptions_throw_privilegedactionexception(java_objectheader *exception)
1621 exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
1626 /* exceptions_throw_stringindexoutofboundsexception ****************************
1628 Generates and throws a java.lang.StringIndexOutOfBoundsException
1631 *******************************************************************************/
1633 void exceptions_throw_stringindexoutofboundsexception(void)
1635 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1639 /* exceptions_classnotfoundexception_to_noclassdeffounderror *******************
1641 Check the exception for a ClassNotFoundException. If it is one,
1642 convert it to a NoClassDefFoundError.
1644 *******************************************************************************/
1646 void exceptions_classnotfoundexception_to_noclassdeffounderror(void)
1648 java_objectheader *o;
1649 java_objectheader *cause;
1650 java_lang_Throwable *object;
1651 java_objectheader *s;
1655 cause = exceptions_get_exception();
1657 /* convert ClassNotFoundException's to NoClassDefFoundError's */
1659 if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
1660 /* clear exception, because we are calling jit code again */
1662 exceptions_clear_exception();
1664 /* create new error */
1666 object = (java_lang_Throwable *) cause;
1667 s = (java_objectheader *) object->detailMessage;
1669 o = exceptions_new_utf_javastring(utf_java_lang_NoClassDefFoundError,
1672 /* we had an exception while creating the error */
1674 if (exceptions_get_exception())
1677 /* set new exception */
1679 exceptions_set_exception(o);
1684 /* exceptions_fillinstacktrace *************************************************
1686 Calls the fillInStackTrace-method of the currently thrown
1689 *******************************************************************************/
1691 java_objectheader *exceptions_fillinstacktrace(void)
1693 java_objectheader *o;
1698 o = exceptions_get_and_clear_exception();
1702 /* resolve methodinfo pointer from exception object */
1704 #if defined(ENABLE_JAVASE)
1705 m = class_resolvemethod(o->vftbl->class,
1706 utf_fillInStackTrace,
1707 utf_void__java_lang_Throwable);
1708 #elif defined(ENABLE_JAVAME_CLDC1_1)
1709 m = class_resolvemethod(o->vftbl->class,
1710 utf_fillInStackTrace,
1713 #error IMPLEMENT ME!
1718 (void) vm_call_method(m, o);
1720 /* return exception object */
1726 /* exceptions_handle_exception *************************************************
1728 Try to find an exception handler for the given exception and return it.
1729 If no handler is found, exit the monitor of the method (if any)
1733 xptr.........the exception object
1734 xpc..........PC of where the exception was thrown
1735 pv...........Procedure Value of the current method
1736 sp...........current stack pointer
1739 the address of the first matching exception handler, or
1740 NULL if no handler was found
1742 *******************************************************************************/
1744 #if defined(ENABLE_JIT)
1745 u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp)
1750 dseg_exception_entry *ex;
1751 s4 exceptiontablelength;
1753 classref_or_classinfo cr;
1755 #if defined(ENABLE_THREADS)
1756 java_objectheader *o;
1760 /* Addresses are 31 bit integers */
1761 # define ADDR_MASK(x) (u1 *)((u4)(x) & 0x7FFFFFFF)
1763 # define ADDR_MASK(x) (x)
1766 xpc = ADDR_MASK(xpc);
1768 /* get info from the method header */
1770 code = *((codeinfo **) (pv + CodeinfoPointer));
1771 issync = *((s4 *) (pv + IsSync));
1772 ex = (dseg_exception_entry *) (pv + ExTableStart);
1773 exceptiontablelength = *((s4 *) (pv + ExTableSize));
1775 /* Get the methodinfo pointer from the codeinfo pointer. For
1776 asm_vm_call_method the codeinfo pointer is NULL. */
1778 m = (code == NULL) ? NULL : code->m;
1780 #if !defined(NDEBUG)
1781 /* print exception trace */
1783 if (opt_verbose || opt_verbosecall || opt_TraceExceptions)
1784 builtin_trace_exception(xptr, m, xpc, 1);
1787 #if defined(ENABLE_VMLOG)
1788 vmlog_cacao_throw(xptr);
1791 for (i = 0; i < exceptiontablelength; i++) {
1792 /* ATTENTION: keep this here, as we need to decrement the
1793 pointer before the loop executes! */
1797 /* If the start and end PC is NULL, this means we have the
1798 special case of asm_vm_call_method. So, just return the
1799 proper exception handler. */
1801 if ((ex->startpc == NULL) && (ex->endpc == NULL))
1802 return (u1 *) (ptrint) &asm_vm_call_method_exception_handler;
1804 /* is the xpc is the current catch range */
1806 if ((ADDR_MASK(ex->startpc) <= xpc) && (xpc < ADDR_MASK(ex->endpc))) {
1809 /* NULL catches everything */
1811 if (cr.any == NULL) {
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_trace(xptr);
1825 return ex->handlerpc;
1828 /* resolve or load/link the exception class */
1830 if (IS_CLASSREF(cr)) {
1831 /* The exception class reference is unresolved. */
1832 /* We have to do _eager_ resolving here. While the class of */
1833 /* the exception object is guaranteed to be loaded, it may */
1834 /* well have been loaded by a different loader than the */
1835 /* defining loader of m's class, which is the one we must */
1836 /* use to resolve the catch class. Thus lazy resolving */
1837 /* might fail, even if the result of the resolution would */
1838 /* be an already loaded class. */
1840 c = resolve_classref_eager(cr.ref);
1843 /* Exception resolving the exception class, argh! */
1847 /* Ok, we resolved it. Enter it in the table, so we don't */
1848 /* have to do this again. */
1849 /* XXX this write should be atomic. Is it? */
1851 ex->catchtype.cls = c;
1855 /* XXX I don't think this case can ever happen. -Edwin */
1856 if (!(c->state & CLASS_LOADED))
1857 /* use the methods' classloader */
1858 if (!load_class_from_classloader(c->name,
1859 m->class->classloader))
1862 /* XXX I think, if it is not linked, we can be sure that */
1863 /* the exception object is no (indirect) instance of it, no? */
1865 if (!(c->state & CLASS_LINKED))
1870 /* is the thrown exception an instance of the catch class? */
1872 if (builtin_instanceof(xptr, c)) {
1873 #if !defined(NDEBUG)
1874 /* Print stacktrace of exception when caught. */
1876 #if defined(ENABLE_VMLOG)
1877 vmlog_cacao_catch(xptr);
1880 if (opt_TraceExceptions) {
1881 exceptions_print_exception(xptr);
1882 stacktrace_print_trace(xptr);
1886 return ex->handlerpc;
1891 #if defined(ENABLE_THREADS)
1892 /* is this method synchronized? */
1895 /* get synchronization object */
1897 # if (defined(__MIPS__) && (SIZEOF_VOID_P == 4)) || defined(__I386__) || defined(__POWERPC__)
1898 /* XXX change this if we ever want to use 4-byte stackslots */
1899 o = *((java_objectheader **) (sp + issync - 8));
1901 o = *((java_objectheader **) (sp + issync - SIZEOF_VOID_P));
1906 lock_monitor_exit(o);
1910 /* none of the exceptions catch this one */
1912 #if defined(ENABLE_VMLOG)
1913 vmlog_cacao_unwnd_method(m);
1918 #endif /* defined(ENABLE_JIT) */
1921 /* exceptions_print_exception **************************************************
1923 Prints an exception, the detail message and the cause, if
1924 available, with CACAO internal functions to stdout.
1926 *******************************************************************************/
1928 void exceptions_print_exception(java_objectheader *xptr)
1930 java_lang_Throwable *t;
1931 #if defined(ENABLE_JAVASE)
1932 java_lang_Throwable *cause;
1936 t = (java_lang_Throwable *) xptr;
1943 #if defined(ENABLE_JAVASE)
1947 /* print the root exception */
1949 utf_display_printable_ascii_classname(t->header.vftbl->class->name);
1951 if (t->detailMessage != NULL) {
1952 u = javastring_toutf((java_objectheader *) t->detailMessage, false);
1955 utf_display_printable_ascii(u);
1960 #if defined(ENABLE_JAVASE)
1961 /* print the cause if available */
1963 if ((cause != NULL) && (cause != t)) {
1964 printf("Caused by: ");
1965 utf_display_printable_ascii_classname(cause->header.vftbl->class->name);
1967 if (cause->detailMessage != NULL) {
1968 u = javastring_toutf((java_objectheader *) cause->detailMessage,
1972 utf_display_printable_ascii(u);
1981 /* exceptions_print_current_exception ******************************************
1983 Prints the current pending exception, the detail message and the
1984 cause, if available, with CACAO internal functions to stdout.
1986 *******************************************************************************/
1988 void exceptions_print_current_exception(void)
1990 java_objectheader *o;
1992 o = exceptions_get_exception();
1994 exceptions_print_exception(o);
1998 /* exceptions_print_stacktrace *************************************************
2000 Prints a pending exception with Throwable.printStackTrace(). If
2001 there happens an exception during printStackTrace(), we print the
2002 thrown exception and the original one.
2004 NOTE: This function calls Java code.
2006 *******************************************************************************/
2008 void exceptions_print_stacktrace(void)
2010 java_objectheader *oxptr;
2011 java_objectheader *xptr;
2015 /* get original exception */
2017 oxptr = exceptions_get_and_clear_exception();
2020 vm_abort("exceptions_print_stacktrace: no exception thrown");
2022 /* clear exception, because we are calling jit code again */
2024 c = oxptr->vftbl->class;
2026 /* find the printStackTrace() method */
2028 m = class_resolveclassmethod(c,
2029 utf_printStackTrace,
2031 class_java_lang_Object,
2035 vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
2037 /* print compatibility message */
2039 fprintf(stderr, "Exception in thread \"main\" ");
2041 /* print the stacktrace */
2043 (void) vm_call_method(m, oxptr);
2045 /* This normally means, we are EXTREMLY out of memory or
2046 have a serious problem while printStackTrace. But may
2047 be another exception, so print it. */
2049 xptr = exceptions_get_exception();
2052 fprintf(stderr, "Exception while printStackTrace(): ");
2054 /* now print original exception */
2056 exceptions_print_exception(xptr);
2057 stacktrace_print_trace(xptr);
2059 /* now print original exception */
2061 fprintf(stderr, "Original exception was: ");
2062 exceptions_print_exception(oxptr);
2063 stacktrace_print_trace(oxptr);
2071 * These are local overrides for various environment variables in Emacs.
2072 * Please do not remove this and leave it at the end of the file, where
2073 * Emacs will automagically detect them.
2074 * ---------------------------------------------------------------------
2077 * indent-tabs-mode: t
2081 * vim:noexpandtab:sw=4:ts=4: