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 8318 2007-08-16 10:05:34Z michi $
43 #include "mm/memory.h"
45 #include "native/jni.h"
46 #include "native/llni.h"
47 #include "native/native.h"
49 #include "native/include/java_lang_String.h"
50 #include "native/include/java_lang_Throwable.h"
52 #include "threads/lock-common.h"
53 #include "threads/threads-common.h"
55 #include "toolbox/util.h"
57 #include "vm/builtin.h"
58 #include "vm/exceptions.h"
59 #include "vm/global.h"
60 #include "vm/stringlocal.h"
63 #include "vm/jit/asmpart.h"
64 #include "vm/jit/jit.h"
65 #include "vm/jit/methodheader.h"
66 #include "vm/jit/patcher-common.h"
67 #include "vm/jit/stacktrace.h"
69 #include "vmcore/class.h"
70 #include "vmcore/loader.h"
71 #include "vmcore/method.h"
72 #include "vmcore/options.h"
74 #if defined(ENABLE_VMLOG)
75 #include <vmlog_cacao.h>
79 /* for raising exceptions from native methods *********************************/
81 #if !defined(ENABLE_THREADS)
82 java_object_t *_no_threads_exceptionptr = NULL;
86 /* init_system_exceptions ******************************************************
88 Load and link exceptions used in the system.
90 *******************************************************************************/
92 bool exceptions_init(void)
94 #if !(defined(__ARM__) && defined(__LINUX__))
95 /* On arm-linux the first memory page can't be mmap'ed, as it
96 contains the exception vectors. */
100 /* mmap a memory page at address 0x0, so our hardware-exceptions
103 pagesize = getpagesize();
105 (void) memory_mmap_anon(NULL, pagesize, PROT_NONE, MAP_PRIVATE | MAP_FIXED);
108 /* check if we get into trouble with our hardware-exceptions */
110 if (OFFSET(java_bytearray_t, data) <= EXCEPTION_HARDWARE_LARGEST)
111 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);
113 /* java/lang/Throwable */
115 if (!(class_java_lang_Throwable =
116 load_class_bootstrap(utf_java_lang_Throwable)) ||
117 !link_class(class_java_lang_Throwable))
120 /* java/lang/Error */
122 if (!(class_java_lang_Error = load_class_bootstrap(utf_java_lang_Error)) ||
123 !link_class(class_java_lang_Error))
126 #if defined(ENABLE_JAVASE)
127 /* java/lang/LinkageError */
129 if (!(class_java_lang_LinkageError =
130 load_class_bootstrap(utf_java_lang_LinkageError)) ||
131 !link_class(class_java_lang_LinkageError))
135 /* java/lang/NoClassDefFoundError */
137 if (!(class_java_lang_NoClassDefFoundError =
138 load_class_bootstrap(utf_java_lang_NoClassDefFoundError)) ||
139 !link_class(class_java_lang_NoClassDefFoundError))
142 /* java/lang/OutOfMemoryError */
144 if (!(class_java_lang_OutOfMemoryError =
145 load_class_bootstrap(utf_java_lang_OutOfMemoryError)) ||
146 !link_class(class_java_lang_OutOfMemoryError))
149 /* java/lang/VirtualMachineError */
151 if (!(class_java_lang_VirtualMachineError =
152 load_class_bootstrap(utf_java_lang_VirtualMachineError)) ||
153 !link_class(class_java_lang_VirtualMachineError))
157 /* java/lang/Exception */
159 if (!(class_java_lang_Exception =
160 load_class_bootstrap(utf_java_lang_Exception)) ||
161 !link_class(class_java_lang_Exception))
164 /* java/lang/ClassCastException */
166 if (!(class_java_lang_ClassCastException =
167 load_class_bootstrap(utf_java_lang_ClassCastException)) ||
168 !link_class(class_java_lang_ClassCastException))
171 /* java/lang/ClassNotFoundException */
173 if (!(class_java_lang_ClassNotFoundException =
174 load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
175 !link_class(class_java_lang_ClassNotFoundException))
178 /* java/lang/NullPointerException */
180 if (!(class_java_lang_NullPointerException =
181 load_class_bootstrap(utf_java_lang_NullPointerException)) ||
182 !link_class(class_java_lang_NullPointerException))
186 #if defined(WITH_CLASSPATH_GNU)
187 /* java/lang/VMThrowable */
189 if (!(class_java_lang_VMThrowable =
190 load_class_bootstrap(utf_java_lang_VMThrowable)) ||
191 !link_class(class_java_lang_VMThrowable))
199 /* exceptions_get_exception ****************************************************
201 Returns the current exception pointer of the current thread.
203 *******************************************************************************/
205 java_handle_t *exceptions_get_exception(void)
207 /* return the exception */
209 return *exceptionptr;
213 /* exceptions_set_exception ****************************************************
215 Sets the exception pointer of the current thread.
217 *******************************************************************************/
219 void exceptions_set_exception(java_handle_t *o)
221 /* set the exception */
227 /* exceptions_clear_exception **************************************************
229 Clears the current exception pointer of the current thread.
231 *******************************************************************************/
233 void exceptions_clear_exception(void)
235 exceptions_set_exception(NULL);
239 /* exceptions_get_and_clear_exception ******************************************
241 Gets the exception pointer of the current thread and clears it.
242 This function may return NULL.
244 *******************************************************************************/
246 java_handle_t *exceptions_get_and_clear_exception(void)
250 /* get the exception */
252 o = exceptions_get_exception();
254 /* and clear the exception */
256 exceptions_clear_exception();
258 /* return the exception */
264 /* exceptions_new_class ********************************************************
266 Creates an exception object from the given class and initalizes it.
269 class....class pointer
271 *******************************************************************************/
273 static java_handle_t *exceptions_new_class(classinfo *c)
277 o = native_new_and_init(c);
280 return exceptions_get_exception();
286 /* exceptions_new_utf **********************************************************
288 Creates an exception object with the given name and initalizes it.
291 classname....class name in UTF-8
293 *******************************************************************************/
295 static java_handle_t *exceptions_new_utf(utf *classname)
300 c = load_class_bootstrap(classname);
303 return exceptions_get_exception();
305 o = exceptions_new_class(c);
311 /* exceptions_throw_class ******************************************************
313 Creates an exception object from the given class, initalizes and
317 class....class pointer
319 *******************************************************************************/
321 static void exceptions_throw_class(classinfo *c)
325 o = exceptions_new_class(c);
330 exceptions_set_exception(o);
334 /* exceptions_throw_utf ********************************************************
336 Creates an exception object with the given name, initalizes and
340 classname....class name in UTF-8
342 *******************************************************************************/
344 static void exceptions_throw_utf(utf *classname)
348 c = load_class_bootstrap(classname);
353 exceptions_throw_class(c);
357 /* exceptions_throw_utf_throwable **********************************************
359 Creates an exception object with the given name and initalizes it
360 with the given java/lang/Throwable exception.
363 classname....class name in UTF-8
364 cause........the given Throwable
366 *******************************************************************************/
368 static void exceptions_throw_utf_throwable(utf *classname,
369 java_handle_t *cause)
374 java_lang_Throwable *object;
376 object = (java_lang_Throwable *) cause;
378 c = load_class_bootstrap(classname);
390 /* call initializer */
392 m = class_resolveclassmethod(c,
394 utf_java_lang_Throwable__void,
401 (void) vm_call_method(m, o, cause);
403 exceptions_set_exception(o);
407 /* exceptions_throw_utf_exception **********************************************
409 Creates an exception object with the given name and initalizes it
410 with the given java/lang/Exception exception.
413 classname....class name in UTF-8
414 exception....the given Exception
416 *******************************************************************************/
418 static void exceptions_throw_utf_exception(utf *classname,
419 java_handle_t *exception)
425 c = load_class_bootstrap(classname);
437 /* call initializer */
439 m = class_resolveclassmethod(c,
441 utf_java_lang_Exception__V,
448 (void) vm_call_method(m, o, exception);
450 exceptions_set_exception(o);
454 /* exceptions_throw_utf_cause **************************************************
456 Creates an exception object with the given name and initalizes it
457 with the given java/lang/Throwable exception with initCause.
460 classname....class name in UTF-8
461 cause........the given Throwable
463 *******************************************************************************/
465 static void exceptions_throw_utf_cause(utf *classname, java_handle_t *cause)
471 java_lang_Throwable *object;
473 object = (java_lang_Throwable *) cause;
475 c = load_class_bootstrap(classname);
487 /* call initializer */
489 m = class_resolveclassmethod(c,
491 utf_java_lang_String__void,
498 LLNI_field_get_ref(object, detailMessage, s);
500 (void) vm_call_method(m, o, s);
504 m = class_resolveclassmethod(c,
506 utf_java_lang_Throwable__java_lang_Throwable,
513 (void) vm_call_method(m, o, cause);
515 exceptions_set_exception(o);
519 /* exceptions_new_utf_javastring ***********************************************
521 Creates an exception object with the given name and initalizes it
522 with the given java/lang/String message.
525 classname....class name in UTF-8
526 message......the message as a java.lang.String
529 an exception pointer (in any case -- either it is the newly created
530 exception, or an exception thrown while trying to create it).
532 *******************************************************************************/
534 static java_handle_t *exceptions_new_utf_javastring(utf *classname,
535 java_handle_t *message)
540 c = load_class_bootstrap(classname);
543 return exceptions_get_exception();
545 o = native_new_and_init_string(c, message);
548 return exceptions_get_exception();
554 /* exceptions_new_class_utf ****************************************************
556 Creates an exception object of the given class and initalizes it.
559 c..........class pointer
560 message....the message as UTF-8 string
562 *******************************************************************************/
564 static java_handle_t *exceptions_new_class_utf(classinfo *c, utf *message)
569 s = javastring_new(message);
572 return exceptions_get_exception();
574 o = native_new_and_init_string(c, s);
577 return exceptions_get_exception();
583 /* exceptions_new_utf_utf ******************************************************
585 Creates an exception object with the given name and initalizes it
586 with the given utf message.
589 classname....class name in UTF-8
590 message......the message as an utf *
593 an exception pointer (in any case -- either it is the newly created
594 exception, or an exception thrown while trying to create it).
596 *******************************************************************************/
598 static java_handle_t *exceptions_new_utf_utf(utf *classname, utf *message)
603 c = load_class_bootstrap(classname);
606 return exceptions_get_exception();
608 o = exceptions_new_class_utf(c, message);
614 /* exceptions_throw_class_utf **************************************************
616 Creates an exception object of the given class, initalizes and
617 throws it with the given utf message.
620 c..........class pointer
621 message....the message as an UTF-8
623 *******************************************************************************/
625 static void exceptions_throw_class_utf(classinfo *c, utf *message)
629 o = exceptions_new_class_utf(c, message);
631 exceptions_set_exception(o);
635 /* exceptions_throw_utf_utf ****************************************************
637 Creates an exception object with the given name, initalizes and
638 throws it with the given utf message.
641 classname....class name in UTF-8
642 message......the message as an utf *
644 *******************************************************************************/
646 static void exceptions_throw_utf_utf(utf *classname, utf *message)
650 o = exceptions_new_utf_utf(classname, message);
652 exceptions_set_exception(o);
656 /* exceptions_new_abstractmethoderror ****************************************
658 Generates a java.lang.AbstractMethodError for the VM.
660 *******************************************************************************/
662 java_handle_t *exceptions_new_abstractmethoderror(void)
666 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
672 /* exceptions_new_error ********************************************************
674 Generates a java.lang.Error for the VM.
676 *******************************************************************************/
678 #if defined(ENABLE_JAVAME_CLDC1_1)
679 static java_handle_t *exceptions_new_error(utf *message)
683 o = exceptions_new_class_utf(class_java_lang_Error, message);
690 /* exceptions_asm_new_abstractmethoderror **************************************
692 Generates a java.lang.AbstractMethodError for
693 asm_abstractmethoderror.
695 *******************************************************************************/
697 java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
702 /* create the stackframeinfo (XPC is equal to RA) */
704 stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra);
706 /* create the exception */
708 #if defined(ENABLE_JAVASE)
709 e = exceptions_new_abstractmethoderror();
711 e = exceptions_new_error(utf_java_lang_AbstractMethodError);
714 /* remove the stackframeinfo */
716 stacktrace_remove_stackframeinfo(&sfi);
722 /* exceptions_new_arraystoreexception ******************************************
724 Generates a java.lang.ArrayStoreException for the VM.
726 *******************************************************************************/
728 java_handle_t *exceptions_new_arraystoreexception(void)
732 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
738 /* exceptions_throw_abstractmethoderror ****************************************
740 Generates and throws a java.lang.AbstractMethodError for the VM.
742 *******************************************************************************/
744 void exceptions_throw_abstractmethoderror(void)
746 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
750 /* exceptions_throw_classcircularityerror **************************************
752 Generates and throws a java.lang.ClassCircularityError for the
756 c....the class in which the error was found
758 *******************************************************************************/
760 void exceptions_throw_classcircularityerror(classinfo *c)
762 exceptions_throw_utf_utf(utf_java_lang_ClassCircularityError, c->name);
766 /* exceptions_throw_classformaterror *******************************************
768 Generates and throws a java.lang.ClassFormatError for the VM.
771 c............the class in which the error was found
772 message......UTF-8 format string
774 *******************************************************************************/
776 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
783 /* calculate message length */
788 msglen += utf_bytes(c->name) + strlen(" (");
790 va_start(ap, message);
791 msglen += get_variable_message_length(message, ap);
795 msglen += strlen(")");
797 msglen += strlen("0");
799 /* allocate a buffer */
801 msg = MNEW(char, msglen);
803 /* print message into allocated buffer */
806 utf_copy_classname(msg, c->name);
810 va_start(ap, message);
811 vsprintf(msg + strlen(msg), message, ap);
817 u = utf_new_char(msg);
821 MFREE(msg, char, msglen);
823 /* throw exception */
825 exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
829 /* exceptions_throw_classnotfoundexception *************************************
831 Generates and throws a java.lang.ClassNotFoundException for the
835 name.........name of the class not found as a utf *
837 *******************************************************************************/
839 void exceptions_throw_classnotfoundexception(utf *name)
841 /* we use class here, as this one is rather frequent */
843 exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
847 /* exceptions_throw_noclassdeffounderror ***************************************
849 Generates and throws a java.lang.NoClassDefFoundError.
852 name.........name of the class not found as a utf *
854 *******************************************************************************/
856 void exceptions_throw_noclassdeffounderror(utf *name)
859 vm_abort("java.lang.NoClassDefFoundError: %s", name->text);
861 exceptions_throw_class_utf(class_java_lang_NoClassDefFoundError, name);
865 /* exceptions_throw_noclassdeffounderror_cause *********************************
867 Generates and throws a java.lang.NoClassDefFoundError with the
870 *******************************************************************************/
872 void exceptions_throw_noclassdeffounderror_cause(java_handle_t *cause)
874 exceptions_throw_utf_cause(utf_java_lang_NoClassDefFoundError, cause);
878 /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
880 Generates and throws a java.lang.NoClassDefFoundError with a
884 name.........name of the class not found as a utf *
886 *******************************************************************************/
888 void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
894 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
895 utf_bytes(name) + strlen(")") + strlen("0");
897 msg = MNEW(char, msglen);
899 utf_copy_classname(msg, c->name);
900 strcat(msg, " (wrong name: ");
901 utf_cat_classname(msg, name);
904 u = utf_new_char(msg);
906 MFREE(msg, char, msglen);
908 exceptions_throw_noclassdeffounderror(u);
912 /* exceptions_throw_exceptionininitializererror ********************************
914 Generates and throws a java.lang.ExceptionInInitializerError for
918 cause......cause exception object
920 *******************************************************************************/
922 void exceptions_throw_exceptionininitializererror(java_handle_t *cause)
924 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
929 /* exceptions_throw_incompatibleclasschangeerror *******************************
931 Generates and throws a java.lang.IncompatibleClassChangeError for
935 message......UTF-8 message format string
937 *******************************************************************************/
939 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
945 /* calculate exception message length */
947 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
949 /* allocate memory */
951 msg = MNEW(char, msglen);
953 utf_copy_classname(msg, c->name);
954 strcat(msg, message);
956 u = utf_new_char(msg);
960 MFREE(msg, char, msglen);
962 /* throw exception */
964 exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
968 /* exceptions_throw_instantiationerror *****************************************
970 Generates and throws a java.lang.InstantiationError for the VM.
972 *******************************************************************************/
974 void exceptions_throw_instantiationerror(classinfo *c)
976 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
980 /* exceptions_throw_internalerror **********************************************
982 Generates and throws a java.lang.InternalError for the VM.
985 message......UTF-8 message format string
987 *******************************************************************************/
989 void exceptions_throw_internalerror(const char *message, ...)
996 /* calculate exception message length */
998 va_start(ap, message);
999 msglen = get_variable_message_length(message, ap);
1002 /* allocate memory */
1004 msg = MNEW(char, msglen);
1006 /* generate message */
1008 va_start(ap, message);
1009 vsprintf(msg, message, ap);
1012 u = utf_new_char(msg);
1016 MFREE(msg, char, msglen);
1018 /* throw exception */
1020 exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
1024 /* exceptions_throw_linkageerror ***********************************************
1026 Generates and throws java.lang.LinkageError with an error message.
1029 message......UTF-8 message
1030 c............class related to the error. If this is != NULL
1031 the name of c is appended to the error message.
1033 *******************************************************************************/
1035 void exceptions_throw_linkageerror(const char *message, classinfo *c)
1041 /* calculate exception message length */
1043 msglen = strlen(message) + 1;
1046 msglen += utf_bytes(c->name);
1048 /* allocate memory */
1050 msg = MNEW(char, msglen);
1052 /* generate message */
1054 strcpy(msg,message);
1057 utf_cat_classname(msg, c->name);
1059 o = native_new_and_init_string(class_java_lang_LinkageError,
1060 javastring_new_from_utf_string(msg));
1064 MFREE(msg, char, msglen);
1069 exceptions_set_exception(o);
1073 /* exceptions_throw_nosuchfielderror *******************************************
1075 Generates and throws a java.lang.NoSuchFieldError with an error
1079 c............class in which the field was not found
1080 name.........name of the field
1082 *******************************************************************************/
1084 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
1090 /* calculate exception message length */
1092 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
1094 /* allocate memory */
1096 msg = MNEW(char, msglen);
1098 /* generate message */
1100 utf_copy_classname(msg, c->name);
1104 u = utf_new_char(msg);
1108 MFREE(msg, char, msglen);
1110 exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
1114 /* exceptions_throw_nosuchmethoderror ******************************************
1116 Generates and throws a java.lang.NoSuchMethodError with an error
1120 c............class in which the method was not found
1121 name.........name of the method
1122 desc.........descriptor of the method
1124 *******************************************************************************/
1126 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
1132 /* calculate exception message length */
1134 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
1135 utf_bytes(desc) + strlen("0");
1137 /* allocate memory */
1139 msg = MNEW(char, msglen);
1141 /* generate message */
1143 utf_copy_classname(msg, c->name);
1148 u = utf_new_char(msg);
1152 MFREE(msg, char, msglen);
1154 #if defined(ENABLE_JAVASE)
1155 exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
1157 exceptions_throw_class_utf(class_java_lang_Error, u);
1162 /* exceptions_throw_outofmemoryerror *******************************************
1164 Generates and throws an java.lang.OutOfMemoryError for the VM.
1166 *******************************************************************************/
1168 void exceptions_throw_outofmemoryerror(void)
1170 exceptions_throw_class(class_java_lang_OutOfMemoryError);
1174 /* exceptions_throw_unsatisfiedlinkerror ***************************************
1176 Generates and throws a java.lang.UnsatisfiedLinkError for the
1180 name......UTF-8 name string
1182 *******************************************************************************/
1184 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1186 #if defined(ENABLE_JAVASE)
1187 exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1189 exceptions_throw_class_utf(class_java_lang_Error, name);
1194 /* exceptions_throw_unsupportedclassversionerror *******************************
1196 Generates and throws a java.lang.UnsupportedClassVersionError for
1200 c............class in which the method was not found
1201 message......UTF-8 format string
1203 *******************************************************************************/
1205 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1211 /* calculate exception message length */
1214 utf_bytes(c->name) +
1215 strlen(" (Unsupported major.minor version 00.0)") +
1218 /* allocate memory */
1220 msg = MNEW(char, msglen);
1222 /* generate message */
1224 utf_copy_classname(msg, c->name);
1225 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1228 u = utf_new_char(msg);
1232 MFREE(msg, char, msglen);
1234 /* throw exception */
1236 exceptions_throw_utf_utf(utf_java_lang_UnsupportedClassVersionError, u);
1240 /* exceptions_throw_verifyerror ************************************************
1242 Generates and throws a java.lang.VerifyError for the JIT compiler.
1245 m............method in which the error was found
1246 message......UTF-8 format string
1248 *******************************************************************************/
1250 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1257 /* calculate exception message length */
1263 strlen("(class: ") + utf_bytes(m->class->name) +
1264 strlen(", method: ") + utf_bytes(m->name) +
1265 strlen(" signature: ") + utf_bytes(m->descriptor) +
1266 strlen(") ") + strlen("0");
1268 va_start(ap, message);
1269 msglen += get_variable_message_length(message, ap);
1272 /* allocate memory */
1274 msg = MNEW(char, msglen);
1276 /* generate message */
1279 strcpy(msg, "(class: ");
1280 utf_cat_classname(msg, m->class->name);
1281 strcat(msg, ", method: ");
1282 utf_cat(msg, m->name);
1283 strcat(msg, " signature: ");
1284 utf_cat(msg, m->descriptor);
1288 va_start(ap, message);
1289 vsprintf(msg + strlen(msg), message, ap);
1292 u = utf_new_char(msg);
1296 MFREE(msg, char, msglen);
1298 /* throw exception */
1300 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1304 /* exceptions_throw_verifyerror_for_stack **************************************
1306 throws a java.lang.VerifyError for an invalid stack slot type
1309 m............method in which the error was found
1310 type.........the expected type
1313 an exception pointer (in any case -- either it is the newly created
1314 exception, or an exception thrown while trying to create it).
1316 *******************************************************************************/
1318 void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
1325 /* calculate exception message length */
1330 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1331 strlen(", method: ") + utf_bytes(m->name) +
1332 strlen(" signature: ") + utf_bytes(m->descriptor) +
1333 strlen(") Expecting to find longest-------typename on stack")
1336 /* allocate memory */
1338 msg = MNEW(char, msglen);
1340 /* generate message */
1343 strcpy(msg, "(class: ");
1344 utf_cat_classname(msg, m->class->name);
1345 strcat(msg, ", method: ");
1346 utf_cat(msg, m->name);
1347 strcat(msg, " signature: ");
1348 utf_cat(msg, m->descriptor);
1355 strcat(msg, "Expecting to find ");
1358 case TYPE_INT: typename = "integer"; break;
1359 case TYPE_LNG: typename = "long"; break;
1360 case TYPE_FLT: typename = "float"; break;
1361 case TYPE_DBL: typename = "double"; break;
1362 case TYPE_ADR: typename = "object/array"; break;
1363 case TYPE_RET: typename = "returnAddress"; break;
1364 default: typename = "<INVALID>"; assert(0); break;
1367 strcat(msg, typename);
1368 strcat(msg, " on stack");
1370 u = utf_new_char(msg);
1374 MFREE(msg, char, msglen);
1376 /* throw exception */
1378 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1382 /* exceptions_new_arithmeticexception ******************************************
1384 Generates a java.lang.ArithmeticException for the JIT compiler.
1386 *******************************************************************************/
1388 java_handle_t *exceptions_new_arithmeticexception(void)
1392 o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
1393 utf_division_by_zero);
1399 /* exceptions_new_arrayindexoutofboundsexception *******************************
1401 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1404 *******************************************************************************/
1406 java_handle_t *exceptions_new_arrayindexoutofboundsexception(s4 index)
1412 /* convert the index into a String, like Sun does */
1414 m = class_resolveclassmethod(class_java_lang_String,
1415 utf_new_char("valueOf"),
1416 utf_new_char("(I)Ljava/lang/String;"),
1417 class_java_lang_Object,
1421 return exceptions_get_exception();
1423 s = vm_call_method(m, NULL, index);
1426 return exceptions_get_exception();
1428 o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1432 return exceptions_get_exception();
1438 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1440 Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1443 *******************************************************************************/
1445 void exceptions_throw_arrayindexoutofboundsexception(void)
1447 exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1451 /* exceptions_throw_arraystoreexception ****************************************
1453 Generates and throws a java.lang.ArrayStoreException for the VM.
1455 *******************************************************************************/
1457 void exceptions_throw_arraystoreexception(void)
1459 exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1460 /* e = native_new_and_init(class_java_lang_ArrayStoreException); */
1464 /* exceptions_new_classcastexception *******************************************
1466 Generates a java.lang.ClassCastException for the JIT compiler.
1468 *******************************************************************************/
1470 java_handle_t *exceptions_new_classcastexception(java_handle_t *o)
1475 classname = o->vftbl->class->name;
1477 e = exceptions_new_class_utf(class_java_lang_ClassCastException, classname);
1483 /* exceptions_throw_clonenotsupportedexception *********************************
1485 Generates and throws a java.lang.CloneNotSupportedException for the
1488 *******************************************************************************/
1490 void exceptions_throw_clonenotsupportedexception(void)
1492 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1496 /* exceptions_throw_illegalaccessexception *************************************
1498 Generates and throws a java.lang.IllegalAccessException for the VM.
1500 *******************************************************************************/
1502 void exceptions_throw_illegalaccessexception(utf *message)
1504 exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
1508 /* exceptions_throw_illegalargumentexception ***********************************
1510 Generates and throws a java.lang.IllegalArgumentException for the
1513 *******************************************************************************/
1515 void exceptions_throw_illegalargumentexception(void)
1517 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1521 /* exceptions_throw_illegalmonitorstateexception *******************************
1523 Generates and throws a java.lang.IllegalMonitorStateException for
1526 *******************************************************************************/
1528 void exceptions_throw_illegalmonitorstateexception(void)
1530 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1534 /* exceptions_throw_instantiationexception *************************************
1536 Generates and throws a java.lang.InstantiationException for the VM.
1538 *******************************************************************************/
1540 void exceptions_throw_instantiationexception(classinfo *c)
1542 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1546 /* exceptions_throw_interruptedexception ***************************************
1548 Generates and throws a java.lang.InterruptedException for the VM.
1550 *******************************************************************************/
1552 void exceptions_throw_interruptedexception(void)
1554 exceptions_throw_utf(utf_java_lang_InterruptedException);
1558 /* exceptions_throw_invocationtargetexception **********************************
1560 Generates and throws a java.lang.reflect.InvocationTargetException
1564 cause......cause exception object
1566 *******************************************************************************/
1568 void exceptions_throw_invocationtargetexception(java_handle_t *cause)
1570 exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1575 /* exceptions_throw_negativearraysizeexception *********************************
1577 Generates and throws a java.lang.NegativeArraySizeException for the
1580 *******************************************************************************/
1582 void exceptions_throw_negativearraysizeexception(void)
1584 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1588 /* exceptions_new_nullpointerexception *****************************************
1590 Generates a java.lang.NullPointerException for the VM system.
1592 *******************************************************************************/
1594 java_handle_t *exceptions_new_nullpointerexception(void)
1598 o = exceptions_new_class(class_java_lang_NullPointerException);
1604 /* exceptions_throw_nullpointerexception ***************************************
1606 Generates a java.lang.NullPointerException for the VM system and
1607 throw it in the VM system.
1609 *******************************************************************************/
1611 void exceptions_throw_nullpointerexception(void)
1613 exceptions_throw_class(class_java_lang_NullPointerException);
1617 /* exceptions_throw_privilegedactionexception **********************************
1619 Generates and throws a java.security.PrivilegedActionException.
1621 *******************************************************************************/
1623 void exceptions_throw_privilegedactionexception(java_handle_t *exception)
1625 exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
1630 /* exceptions_throw_stringindexoutofboundsexception ****************************
1632 Generates and throws a java.lang.StringIndexOutOfBoundsException
1635 *******************************************************************************/
1637 void exceptions_throw_stringindexoutofboundsexception(void)
1639 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1643 /* exceptions_classnotfoundexception_to_noclassdeffounderror *******************
1645 Check the exception for a ClassNotFoundException. If it is one,
1646 convert it to a NoClassDefFoundError.
1648 *******************************************************************************/
1650 void exceptions_classnotfoundexception_to_noclassdeffounderror(void)
1653 java_handle_t *cause;
1654 java_lang_Throwable *object;
1655 java_lang_String *s;
1659 cause = exceptions_get_exception();
1661 /* convert ClassNotFoundException's to NoClassDefFoundError's */
1663 if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
1664 /* clear exception, because we are calling jit code again */
1666 exceptions_clear_exception();
1668 /* create new error */
1670 object = (java_lang_Throwable *) cause;
1671 LLNI_field_get_ref(object, detailMessage, s);
1673 o = exceptions_new_utf_javastring(utf_java_lang_NoClassDefFoundError,
1674 (java_handle_t *) s);
1676 /* we had an exception while creating the error */
1678 if (exceptions_get_exception())
1681 /* set new exception */
1683 exceptions_set_exception(o);
1688 /* exceptions_fillinstacktrace *************************************************
1690 Calls the fillInStackTrace-method of the currently thrown
1693 *******************************************************************************/
1695 java_handle_t *exceptions_fillinstacktrace(void)
1702 o = exceptions_get_and_clear_exception();
1706 /* resolve methodinfo pointer from exception object */
1708 #if defined(ENABLE_JAVASE)
1709 m = class_resolvemethod(o->vftbl->class,
1710 utf_fillInStackTrace,
1711 utf_void__java_lang_Throwable);
1712 #elif defined(ENABLE_JAVAME_CLDC1_1)
1713 m = class_resolvemethod(o->vftbl->class,
1714 utf_fillInStackTrace,
1717 #error IMPLEMENT ME!
1722 (void) vm_call_method(m, o);
1724 /* return exception object */
1730 /* exceptions_handle_exception *************************************************
1732 Try to find an exception handler for the given exception and return it.
1733 If no handler is found, exit the monitor of the method (if any)
1737 xptr.........the exception object
1738 xpc..........PC of where the exception was thrown
1739 pv...........Procedure Value of the current method
1740 sp...........current stack pointer
1743 the address of the first matching exception handler, or
1744 NULL if no handler was found
1746 *******************************************************************************/
1748 #if defined(ENABLE_JIT)
1749 u1 *exceptions_handle_exception(java_object_t *xptr, u1 *xpc, u1 *pv, u1 *sp)
1754 dseg_exception_entry *ex;
1755 s4 exceptiontablelength;
1757 classref_or_classinfo cr;
1759 #if defined(ENABLE_THREADS)
1764 /* Addresses are 31 bit integers */
1765 # define ADDR_MASK(x) (u1 *)((u4)(x) & 0x7FFFFFFF)
1767 # define ADDR_MASK(x) (x)
1770 xpc = ADDR_MASK(xpc);
1772 /* get info from the method header */
1774 code = *((codeinfo **) (pv + CodeinfoPointer));
1775 issync = *((s4 *) (pv + IsSync));
1776 ex = (dseg_exception_entry *) (pv + ExTableStart);
1777 exceptiontablelength = *((s4 *) (pv + ExTableSize));
1779 /* Get the methodinfo pointer from the codeinfo pointer. For
1780 asm_vm_call_method the codeinfo pointer is NULL. */
1782 m = (code == NULL) ? NULL : code->m;
1784 #if !defined(NDEBUG)
1785 /* print exception trace */
1787 if (opt_verbose || opt_verbosecall || opt_TraceExceptions)
1788 builtin_trace_exception(xptr, m, xpc, 1);
1791 #if defined(ENABLE_VMLOG)
1792 vmlog_cacao_throw(xptr);
1795 for (i = 0; i < exceptiontablelength; i++) {
1796 /* ATTENTION: keep this here, as we need to decrement the
1797 pointer before the loop executes! */
1801 /* If the start and end PC is NULL, this means we have the
1802 special case of asm_vm_call_method. So, just return the
1803 proper exception handler. */
1805 if ((ex->startpc == NULL) && (ex->endpc == NULL))
1806 return (u1 *) (ptrint) &asm_vm_call_method_exception_handler;
1808 /* is the xpc is the current catch range */
1810 if ((ADDR_MASK(ex->startpc) <= xpc) && (xpc < ADDR_MASK(ex->endpc))) {
1813 /* NULL catches everything */
1815 if (cr.any == NULL) {
1816 #if !defined(NDEBUG)
1817 /* Print stacktrace of exception when caught. */
1819 #if defined(ENABLE_VMLOG)
1820 vmlog_cacao_catch(xptr);
1823 if (opt_TraceExceptions) {
1824 exceptions_print_exception(xptr);
1825 stacktrace_print_trace(xptr);
1829 return ex->handlerpc;
1832 /* resolve or load/link the exception class */
1834 if (IS_CLASSREF(cr)) {
1835 /* The exception class reference is unresolved. */
1836 /* We have to do _eager_ resolving here. While the class of */
1837 /* the exception object is guaranteed to be loaded, it may */
1838 /* well have been loaded by a different loader than the */
1839 /* defining loader of m's class, which is the one we must */
1840 /* use to resolve the catch class. Thus lazy resolving */
1841 /* might fail, even if the result of the resolution would */
1842 /* be an already loaded class. */
1844 c = resolve_classref_eager(cr.ref);
1847 /* Exception resolving the exception class, argh! */
1851 /* Ok, we resolved it. Enter it in the table, so we don't */
1852 /* have to do this again. */
1853 /* XXX this write should be atomic. Is it? */
1855 ex->catchtype.cls = c;
1859 /* XXX I don't think this case can ever happen. -Edwin */
1860 if (!(c->state & CLASS_LOADED))
1861 /* use the methods' classloader */
1862 if (!load_class_from_classloader(c->name,
1863 m->class->classloader))
1866 /* XXX I think, if it is not linked, we can be sure that */
1867 /* the exception object is no (indirect) instance of it, no? */
1869 if (!(c->state & CLASS_LINKED))
1874 /* is the thrown exception an instance of the catch class? */
1876 if (builtin_instanceof(xptr, c)) {
1877 #if !defined(NDEBUG)
1878 /* Print stacktrace of exception when caught. */
1880 #if defined(ENABLE_VMLOG)
1881 vmlog_cacao_catch(xptr);
1884 if (opt_TraceExceptions) {
1885 exceptions_print_exception(xptr);
1886 stacktrace_print_trace(xptr);
1890 return ex->handlerpc;
1895 #if defined(ENABLE_THREADS)
1896 /* is this method synchronized? */
1899 /* get synchronization object */
1901 # if (defined(__MIPS__) && (SIZEOF_VOID_P == 4)) || defined(__I386__) || defined(__S390__) || defined(__POWERPC__)
1902 /* XXX change this if we ever want to use 4-byte stackslots */
1903 o = *((java_object_t **) (sp + issync - 8));
1905 o = *((java_object_t **) (sp + issync - SIZEOF_VOID_P));
1910 lock_monitor_exit(o);
1914 /* none of the exceptions catch this one */
1916 #if defined(ENABLE_VMLOG)
1917 vmlog_cacao_unwnd_method(m);
1922 #endif /* defined(ENABLE_JIT) */
1925 /* exceptions_print_exception **************************************************
1927 Prints an exception, the detail message and the cause, if
1928 available, with CACAO internal functions to stdout.
1930 *******************************************************************************/
1932 void exceptions_print_exception(java_handle_t *xptr)
1934 java_lang_Throwable *t;
1935 #if defined(ENABLE_JAVASE)
1936 java_lang_Throwable *cause;
1938 java_lang_String *s;
1942 t = (java_lang_Throwable *) xptr;
1949 #if defined(ENABLE_JAVASE)
1950 LLNI_field_get_ref(t, cause, cause);
1953 /* print the root exception */
1955 LLNI_class_get(t, c);
1956 utf_display_printable_ascii_classname(c->name);
1958 LLNI_field_get_ref(t, detailMessage, s);
1961 u = javastring_toutf((java_handle_t *) s, false);
1964 utf_display_printable_ascii(u);
1969 #if defined(ENABLE_JAVASE)
1970 /* print the cause if available */
1972 if ((cause != NULL) && (cause != t)) {
1973 printf("Caused by: ");
1975 LLNI_class_get(cause, c);
1976 utf_display_printable_ascii_classname(c->name);
1978 LLNI_field_get_ref(cause, detailMessage, s);
1981 u = javastring_toutf((java_handle_t *) s, false);
1984 utf_display_printable_ascii(u);
1993 /* exceptions_print_current_exception ******************************************
1995 Prints the current pending exception, the detail message and the
1996 cause, if available, with CACAO internal functions to stdout.
1998 *******************************************************************************/
2000 void exceptions_print_current_exception(void)
2004 o = exceptions_get_exception();
2006 exceptions_print_exception(o);
2010 /* exceptions_print_stacktrace *************************************************
2012 Prints a pending exception with Throwable.printStackTrace(). If
2013 there happens an exception during printStackTrace(), we print the
2014 thrown exception and the original one.
2016 NOTE: This function calls Java code.
2018 *******************************************************************************/
2020 void exceptions_print_stacktrace(void)
2022 java_handle_t *oxptr;
2023 java_handle_t *xptr;
2027 /* get original exception */
2029 oxptr = exceptions_get_and_clear_exception();
2032 vm_abort("exceptions_print_stacktrace: no exception thrown");
2034 /* clear exception, because we are calling jit code again */
2036 c = oxptr->vftbl->class;
2038 /* find the printStackTrace() method */
2040 m = class_resolveclassmethod(c,
2041 utf_printStackTrace,
2043 class_java_lang_Object,
2047 vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
2049 /* print compatibility message */
2051 fprintf(stderr, "Exception in thread \"main\" ");
2053 /* print the stacktrace */
2055 (void) vm_call_method(m, oxptr);
2057 /* This normally means, we are EXTREMLY out of memory or
2058 have a serious problem while printStackTrace. But may
2059 be another exception, so print it. */
2061 xptr = exceptions_get_exception();
2064 fprintf(stderr, "Exception while printStackTrace(): ");
2066 /* now print original exception */
2068 exceptions_print_exception(xptr);
2069 stacktrace_print_trace(xptr);
2071 /* now print original exception */
2073 fprintf(stderr, "Original exception was: ");
2074 exceptions_print_exception(oxptr);
2075 stacktrace_print_trace(oxptr);
2083 * These are local overrides for various environment variables in Emacs.
2084 * Please do not remove this and leave it at the end of the file, where
2085 * Emacs will automagically detect them.
2086 * ---------------------------------------------------------------------
2089 * indent-tabs-mode: t
2093 * vim:noexpandtab:sw=4:ts=4: