1 /* src/vm/exceptions.cpp - exception related functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
38 #include "mm/memory.h"
40 #include "native/jni.h"
41 #include "native/llni.h"
42 #include "native/native.h"
44 #include "threads/lock-common.h"
45 #include "threads/thread.hpp"
47 #include "toolbox/util.h"
49 #include "vm/builtin.h"
50 #include "vm/exceptions.hpp"
51 #include "vm/global.h"
52 #include "vm/string.hpp"
55 #include "vm/jit/asmpart.h"
56 #include "vm/jit/jit.h"
57 #include "vm/jit/methodheader.h"
58 #include "vm/jit/patcher-common.h"
59 #include "vm/jit/show.h"
60 #include "vm/jit/stacktrace.hpp"
61 #include "vm/jit/trace.hpp"
63 #include "vmcore/class.h"
64 #include "vmcore/globals.hpp"
65 #include "vmcore/javaobjects.hpp"
66 #include "vmcore/loader.h"
67 #include "vmcore/method.h"
68 #include "vmcore/options.h"
69 #include "vmcore/os.hpp"
71 #if defined(ENABLE_VMLOG)
72 #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 /* exceptions_get_exception ****************************************************
88 Returns the current exception pointer of the current thread.
90 *******************************************************************************/
92 java_handle_t *exceptions_get_exception(void)
96 #if defined(ENABLE_THREADS)
102 /* Get the exception. */
106 #if defined(ENABLE_THREADS)
107 o = t->_exceptionptr;
109 o = _no_threads_exceptionptr;
116 /* Return the exception. */
122 /* exceptions_set_exception ****************************************************
124 Sets the exception pointer of the current thread.
126 *******************************************************************************/
128 void exceptions_set_exception(java_handle_t *e)
133 #if defined(ENABLE_THREADS)
139 /* Set the exception. */
146 if (opt_DebugExceptions) {
147 printf("[exceptions_set_exception : t=%p, o=%p, class=",
148 (void *) t, (void *) o);
149 class_print(o->vftbl->clazz);
154 #if defined(ENABLE_THREADS)
155 t->_exceptionptr = o;
157 _no_threads_exceptionptr = o;
164 /* exceptions_clear_exception **************************************************
166 Clears the current exception pointer of the current thread.
168 *******************************************************************************/
170 void exceptions_clear_exception(void)
174 #if defined(ENABLE_THREADS)
180 /* Set the exception. */
183 if (opt_DebugExceptions) {
184 printf("[exceptions_clear_exception: t=%p]\n", (void *) t);
188 #if defined(ENABLE_THREADS)
189 t->_exceptionptr = NULL;
191 _no_threads_exceptionptr = NULL;
196 /* exceptions_get_and_clear_exception ******************************************
198 Gets the exception pointer of the current thread and clears it.
199 This function may return NULL.
201 *******************************************************************************/
203 java_handle_t *exceptions_get_and_clear_exception(void)
207 /* Get the exception... */
209 o = exceptions_get_exception();
211 /* ...and clear the exception if it is set. */
214 exceptions_clear_exception();
216 /* return the exception */
222 /* exceptions_abort ************************************************************
224 Prints exception to be thrown and aborts.
227 classname....class name
228 message......exception message
230 *******************************************************************************/
232 static void exceptions_abort(utf *classname, utf *message)
234 log_println("exception thrown while VM is initializing: ");
237 utf_display_printable_ascii_classname(classname);
239 if (message != NULL) {
241 utf_display_printable_ascii_classname(message);
246 vm_abort("Aborting...");
250 /* exceptions_new_class_utf ****************************************************
252 Creates an exception object with the given class and initalizes it
253 with the given utf message.
256 c ......... exception class
257 message ... the message as an utf *
260 an exception pointer (in any case -- either it is the newly
261 created exception, or an exception thrown while trying to create
264 *******************************************************************************/
266 static java_handle_t *exceptions_new_class_utf(classinfo *c, utf *message)
271 if (vm->is_initializing()) {
272 /* This can happen when global class variables are used which
273 are not initialized yet. */
276 exceptions_abort(NULL, message);
278 exceptions_abort(c->name, message);
281 s = javastring_new(message);
284 return exceptions_get_exception();
286 o = native_new_and_init_string(c, s);
289 return exceptions_get_exception();
295 /* exceptions_new_utf **********************************************************
297 Creates an exception object with the given name and initalizes it.
300 classname....class name in UTF-8
302 *******************************************************************************/
304 static java_handle_t *exceptions_new_utf(utf *classname)
309 if (vm->is_initializing())
310 exceptions_abort(classname, NULL);
312 c = load_class_bootstrap(classname);
315 return exceptions_get_exception();
317 o = native_new_and_init(c);
320 return exceptions_get_exception();
326 /* exceptions_new_utf_javastring ***********************************************
328 Creates an exception object with the given name and initalizes it
329 with the given java/lang/String message.
332 classname....class name in UTF-8
333 message......the message as a java.lang.String
336 an exception pointer (in any case -- either it is the newly created
337 exception, or an exception thrown while trying to create it).
339 *******************************************************************************/
341 static java_handle_t *exceptions_new_utf_javastring(utf *classname,
342 java_handle_t *message)
347 if (vm->is_initializing())
348 exceptions_abort(classname, NULL);
350 c = load_class_bootstrap(classname);
353 return exceptions_get_exception();
355 o = native_new_and_init_string(c, message);
358 return exceptions_get_exception();
364 /* exceptions_new_utf_utf ******************************************************
366 Creates an exception object with the given name and initalizes it
367 with the given utf message.
370 classname....class name in UTF-8
371 message......the message as an utf *
374 an exception pointer (in any case -- either it is the newly created
375 exception, or an exception thrown while trying to create it).
377 *******************************************************************************/
379 static java_handle_t *exceptions_new_utf_utf(utf *classname, utf *message)
384 if (vm->is_initializing())
385 exceptions_abort(classname, message);
387 c = load_class_bootstrap(classname);
390 return exceptions_get_exception();
392 o = exceptions_new_class_utf(c, message);
398 /* exceptions_throw_class_utf **************************************************
400 Creates an exception object with the given class, initalizes and
401 throws it with the given utf message.
404 c ......... exception class
405 message ... the message as an utf *
407 *******************************************************************************/
409 static void exceptions_throw_class_utf(classinfo *c, utf *message)
413 o = exceptions_new_class_utf(c, message);
415 exceptions_set_exception(o);
419 /* exceptions_throw_utf ********************************************************
421 Creates an exception object with the given name, initalizes and
425 classname....class name in UTF-8
427 *******************************************************************************/
429 static void exceptions_throw_utf(utf *classname)
433 o = exceptions_new_utf(classname);
438 exceptions_set_exception(o);
442 /* exceptions_throw_utf_throwable **********************************************
444 Creates an exception object with the given name and initalizes it
445 with the given java/lang/Throwable exception.
448 classname....class name in UTF-8
449 cause........the given Throwable
451 *******************************************************************************/
453 static void exceptions_throw_utf_throwable(utf *classname,
454 java_handle_t *cause)
459 if (vm->is_initializing())
460 exceptions_abort(classname, NULL);
462 java_lang_Throwable jlt(cause);
464 c = load_class_bootstrap(classname);
471 java_handle_t* h = builtin_new(c);
476 /* call initializer */
478 m = class_resolveclassmethod(c,
480 utf_java_lang_Throwable__void,
487 (void) vm_call_method(m, h, jlt.get_handle());
489 exceptions_set_exception(h);
493 /* exceptions_throw_utf_exception **********************************************
495 Creates an exception object with the given name and initalizes it
496 with the given java/lang/Exception exception.
499 classname....class name in UTF-8
500 exception....the given Exception
502 *******************************************************************************/
504 static void exceptions_throw_utf_exception(utf *classname,
505 java_handle_t *exception)
511 if (vm->is_initializing())
512 exceptions_abort(classname, NULL);
514 c = load_class_bootstrap(classname);
526 /* call initializer */
528 m = class_resolveclassmethod(c,
530 utf_java_lang_Exception__V,
537 (void) vm_call_method(m, o, exception);
539 exceptions_set_exception(o);
543 /* exceptions_throw_utf_cause **************************************************
545 Creates an exception object with the given name and initalizes it
546 with the given java/lang/Throwable exception with initCause.
549 classname....class name in UTF-8
550 cause........the given Throwable
552 *******************************************************************************/
554 static void exceptions_throw_utf_cause(utf *classname, java_handle_t *cause)
556 if (vm->is_initializing())
557 exceptions_abort(classname, NULL);
559 java_lang_Throwable jltcause(cause);
561 classinfo* c = load_class_bootstrap(classname);
568 java_handle_t* h = builtin_new(c);
573 /* call initializer */
575 methodinfo* m = class_resolveclassmethod(c,
577 utf_java_lang_String__void,
584 (void) vm_call_method(m, h, jltcause.get_detailMessage());
588 m = class_resolveclassmethod(c,
590 utf_java_lang_Throwable__java_lang_Throwable,
597 (void) vm_call_method(m, h, jltcause.get_handle());
599 exceptions_set_exception(h);
603 /* exceptions_throw_utf_utf ****************************************************
605 Creates an exception object with the given name, initalizes and
606 throws it with the given utf message.
609 classname....class name in UTF-8
610 message......the message as an utf *
612 *******************************************************************************/
614 static void exceptions_throw_utf_utf(utf *classname, utf *message)
618 o = exceptions_new_utf_utf(classname, message);
620 exceptions_set_exception(o);
624 /* exceptions_new_abstractmethoderror ****************************************
626 Generates a java.lang.AbstractMethodError for the VM.
628 *******************************************************************************/
630 java_handle_t *exceptions_new_abstractmethoderror(void)
634 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
640 /* exceptions_new_error ********************************************************
642 Generates a java.lang.Error for the VM.
644 *******************************************************************************/
646 #if defined(ENABLE_JAVAME_CLDC1_1)
647 static java_handle_t *exceptions_new_error(utf *message)
651 o = exceptions_new_utf_utf(utf_java_lang_Error, message);
658 /* exceptions_asm_new_abstractmethoderror **************************************
660 Generates a java.lang.AbstractMethodError for
661 asm_abstractmethoderror.
663 *******************************************************************************/
665 java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
667 stackframeinfo_t sfi;
671 /* Fill and add a stackframeinfo (XPC is equal to RA). */
673 stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra);
675 /* create the exception */
677 #if defined(ENABLE_JAVASE)
678 e = exceptions_new_abstractmethoderror();
680 e = exceptions_new_error(utf_java_lang_AbstractMethodError);
683 /* Remove the stackframeinfo. */
685 stacktrace_stackframeinfo_remove(&sfi);
687 /* unwrap the exception */
688 /* ATTENTION: do the this _after_ the stackframeinfo was removed */
696 /* exceptions_new_arraystoreexception ******************************************
698 Generates a java.lang.ArrayStoreException for the VM.
700 *******************************************************************************/
702 java_handle_t *exceptions_new_arraystoreexception(void)
706 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
712 /* exceptions_throw_abstractmethoderror ****************************************
714 Generates and throws a java.lang.AbstractMethodError for the VM.
716 *******************************************************************************/
718 void exceptions_throw_abstractmethoderror(void)
720 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
724 /* exceptions_throw_classcircularityerror **************************************
726 Generates and throws a java.lang.ClassCircularityError for the
730 c....the class in which the error was found
732 *******************************************************************************/
734 void exceptions_throw_classcircularityerror(classinfo *c)
736 exceptions_throw_utf_utf(utf_java_lang_ClassCircularityError, c->name);
740 /* exceptions_throw_classformaterror *******************************************
742 Generates and throws a java.lang.ClassFormatError for the VM.
745 c............the class in which the error was found
746 message......UTF-8 format string
748 *******************************************************************************/
750 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
757 /* calculate message length */
762 msglen += utf_bytes(c->name) + strlen(" (");
764 va_start(ap, message);
765 msglen += get_variable_message_length(message, ap);
769 msglen += strlen(")");
771 msglen += strlen("0");
773 /* allocate a buffer */
775 msg = MNEW(char, msglen);
777 /* print message into allocated buffer */
780 utf_copy_classname(msg, c->name);
784 va_start(ap, message);
785 vsprintf(msg + strlen(msg), message, ap);
791 u = utf_new_char(msg);
795 MFREE(msg, char, msglen);
797 /* throw exception */
799 exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
803 /* exceptions_throw_classnotfoundexception *************************************
805 Generates and throws a java.lang.ClassNotFoundException for the
809 name.........name of the class not found as a utf *
811 *******************************************************************************/
813 void exceptions_throw_classnotfoundexception(utf *name)
815 exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
819 /* exceptions_throw_noclassdeffounderror ***************************************
821 Generates and throws a java.lang.NoClassDefFoundError.
824 name.........name of the class not found as a utf *
826 *******************************************************************************/
828 void exceptions_throw_noclassdeffounderror(utf *name)
830 exceptions_throw_utf_utf(utf_java_lang_NoClassDefFoundError, name);
834 /* exceptions_throw_noclassdeffounderror_cause *********************************
836 Generates and throws a java.lang.NoClassDefFoundError with the
839 *******************************************************************************/
841 void exceptions_throw_noclassdeffounderror_cause(java_handle_t *cause)
843 exceptions_throw_utf_cause(utf_java_lang_NoClassDefFoundError, cause);
847 /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
849 Generates and throws a java.lang.NoClassDefFoundError with a
853 name.........name of the class not found as a utf *
855 *******************************************************************************/
857 void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
863 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
864 utf_bytes(name) + strlen(")") + strlen("0");
866 msg = MNEW(char, msglen);
868 utf_copy_classname(msg, c->name);
869 strcat(msg, " (wrong name: ");
870 utf_cat_classname(msg, name);
873 u = utf_new_char(msg);
875 MFREE(msg, char, msglen);
877 exceptions_throw_noclassdeffounderror(u);
881 /* exceptions_throw_exceptionininitializererror ********************************
883 Generates and throws a java.lang.ExceptionInInitializerError for
887 cause......cause exception object
889 *******************************************************************************/
891 void exceptions_throw_exceptionininitializererror(java_handle_t *cause)
893 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
898 /* exceptions_throw_incompatibleclasschangeerror *******************************
900 Generates and throws a java.lang.IncompatibleClassChangeError for
904 message......UTF-8 message format string
906 *******************************************************************************/
908 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
914 /* calculate exception message length */
916 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
918 /* allocate memory */
920 msg = MNEW(char, msglen);
922 utf_copy_classname(msg, c->name);
923 strcat(msg, message);
925 u = utf_new_char(msg);
929 MFREE(msg, char, msglen);
931 /* throw exception */
933 exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
937 /* exceptions_throw_instantiationerror *****************************************
939 Generates and throws a java.lang.InstantiationError for the VM.
941 *******************************************************************************/
943 void exceptions_throw_instantiationerror(classinfo *c)
945 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
949 /* exceptions_throw_internalerror **********************************************
951 Generates and throws a java.lang.InternalError for the VM.
954 message......UTF-8 message format string
956 *******************************************************************************/
958 void exceptions_throw_internalerror(const char *message, ...)
965 /* calculate exception message length */
967 va_start(ap, message);
968 msglen = get_variable_message_length(message, ap);
971 /* allocate memory */
973 msg = MNEW(char, msglen);
975 /* generate message */
977 va_start(ap, message);
978 vsprintf(msg, message, ap);
981 u = utf_new_char(msg);
985 MFREE(msg, char, msglen);
987 /* throw exception */
989 exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
993 /* exceptions_throw_linkageerror ***********************************************
995 Generates and throws java.lang.LinkageError with an error message.
998 message......UTF-8 message
999 c............class related to the error. If this is != NULL
1000 the name of c is appended to the error message.
1002 *******************************************************************************/
1004 void exceptions_throw_linkageerror(const char *message, classinfo *c)
1010 /* calculate exception message length */
1012 len = strlen(message) + 1;
1015 len += utf_bytes(c->name);
1017 /* allocate memory */
1019 msg = MNEW(char, len);
1021 /* generate message */
1023 strcpy(msg, message);
1026 utf_cat_classname(msg, c->name);
1028 u = utf_new_char(msg);
1032 MFREE(msg, char, len);
1034 exceptions_throw_utf_utf(utf_java_lang_LinkageError, u);
1038 /* exceptions_throw_nosuchfielderror *******************************************
1040 Generates and throws a java.lang.NoSuchFieldError with an error
1044 c............class in which the field was not found
1045 name.........name of the field
1047 *******************************************************************************/
1049 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
1055 /* calculate exception message length */
1057 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
1059 /* allocate memory */
1061 msg = MNEW(char, msglen);
1063 /* generate message */
1065 utf_copy_classname(msg, c->name);
1069 u = utf_new_char(msg);
1073 MFREE(msg, char, msglen);
1075 exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
1079 /* exceptions_throw_nosuchmethoderror ******************************************
1081 Generates and throws a java.lang.NoSuchMethodError with an error
1085 c............class in which the method was not found
1086 name.........name of the method
1087 desc.........descriptor of the method
1089 *******************************************************************************/
1091 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
1097 /* calculate exception message length */
1099 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
1100 utf_bytes(desc) + strlen("0");
1102 /* allocate memory */
1104 msg = MNEW(char, msglen);
1106 /* generate message */
1108 utf_copy_classname(msg, c->name);
1113 u = utf_new_char(msg);
1117 MFREE(msg, char, msglen);
1119 #if defined(ENABLE_JAVASE)
1120 exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
1122 exceptions_throw_utf_utf(utf_java_lang_Error, u);
1127 /* exceptions_throw_outofmemoryerror *******************************************
1129 Generates and throws an java.lang.OutOfMemoryError for the VM.
1131 *******************************************************************************/
1133 void exceptions_throw_outofmemoryerror(void)
1135 exceptions_throw_utf(utf_java_lang_OutOfMemoryError);
1139 /* exceptions_throw_unsatisfiedlinkerror ***************************************
1141 Generates and throws a java.lang.UnsatisfiedLinkError for the
1145 name......UTF-8 name string
1147 *******************************************************************************/
1149 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1151 #if defined(ENABLE_JAVASE)
1152 exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1154 exceptions_throw_utf_utf(utf_java_lang_Error, name);
1159 /* exceptions_throw_unsupportedclassversionerror *******************************
1161 Generates and throws a java.lang.UnsupportedClassVersionError for
1165 c............class in which the method was not found
1166 message......UTF-8 format string
1168 *******************************************************************************/
1170 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1176 /* calculate exception message length */
1179 utf_bytes(c->name) +
1180 strlen(" (Unsupported major.minor version 00.0)") +
1183 /* allocate memory */
1185 msg = MNEW(char, msglen);
1187 /* generate message */
1189 utf_copy_classname(msg, c->name);
1190 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1193 u = utf_new_char(msg);
1197 MFREE(msg, char, msglen);
1199 /* throw exception */
1201 exceptions_throw_utf_utf(utf_java_lang_UnsupportedClassVersionError, u);
1205 /* exceptions_throw_verifyerror ************************************************
1207 Generates and throws a java.lang.VerifyError for the JIT compiler.
1210 m............method in which the error was found
1211 message......UTF-8 format string
1213 *******************************************************************************/
1215 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1222 /* calculate exception message length */
1228 strlen("(class: ") + utf_bytes(m->clazz->name) +
1229 strlen(", method: ") + utf_bytes(m->name) +
1230 strlen(" signature: ") + utf_bytes(m->descriptor) +
1231 strlen(") ") + strlen("0");
1233 va_start(ap, message);
1234 msglen += get_variable_message_length(message, ap);
1237 /* allocate memory */
1239 msg = MNEW(char, msglen);
1241 /* generate message */
1244 strcpy(msg, "(class: ");
1245 utf_cat_classname(msg, m->clazz->name);
1246 strcat(msg, ", method: ");
1247 utf_cat(msg, m->name);
1248 strcat(msg, " signature: ");
1249 utf_cat(msg, m->descriptor);
1253 va_start(ap, message);
1254 vsprintf(msg + strlen(msg), message, ap);
1257 u = utf_new_char(msg);
1261 MFREE(msg, char, msglen);
1263 /* throw exception */
1265 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1269 /* exceptions_throw_verifyerror_for_stack **************************************
1271 throws a java.lang.VerifyError for an invalid stack slot type
1274 m............method in which the error was found
1275 type.........the expected type
1278 an exception pointer (in any case -- either it is the newly created
1279 exception, or an exception thrown while trying to create it).
1281 *******************************************************************************/
1283 void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
1289 /* calculate exception message length */
1294 msglen = strlen("(class: ") + utf_bytes(m->clazz->name) +
1295 strlen(", method: ") + utf_bytes(m->name) +
1296 strlen(" signature: ") + utf_bytes(m->descriptor) +
1297 strlen(") Expecting to find longest-------typename on stack")
1300 /* allocate memory */
1302 msg = MNEW(char, msglen);
1304 /* generate message */
1307 strcpy(msg, "(class: ");
1308 utf_cat_classname(msg, m->clazz->name);
1309 strcat(msg, ", method: ");
1310 utf_cat(msg, m->name);
1311 strcat(msg, " signature: ");
1312 utf_cat(msg, m->descriptor);
1319 strcat(msg, "Expecting to find ");
1324 case TYPE_INT: name = "integer"; break;
1325 case TYPE_LNG: name = "long"; break;
1326 case TYPE_FLT: name = "float"; break;
1327 case TYPE_DBL: name = "double"; break;
1328 case TYPE_ADR: name = "object/array"; break;
1329 case TYPE_RET: name = "returnAddress"; break;
1330 default: name = "<INVALID>"; assert(0); break;
1334 strcat(msg, " on stack");
1336 u = utf_new_char(msg);
1340 MFREE(msg, char, msglen);
1342 /* throw exception */
1344 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1348 /* exceptions_new_arithmeticexception ******************************************
1350 Generates a java.lang.ArithmeticException for the JIT compiler.
1352 *******************************************************************************/
1354 java_handle_t *exceptions_new_arithmeticexception(void)
1358 o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
1359 utf_division_by_zero);
1365 /* exceptions_new_arrayindexoutofboundsexception *******************************
1367 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1370 *******************************************************************************/
1372 java_handle_t *exceptions_new_arrayindexoutofboundsexception(s4 index)
1378 /* convert the index into a String, like Sun does */
1380 m = class_resolveclassmethod(class_java_lang_String,
1381 utf_new_char("valueOf"),
1382 utf_new_char("(I)Ljava/lang/String;"),
1383 class_java_lang_Object,
1387 return exceptions_get_exception();
1389 s = vm_call_method(m, NULL, index);
1392 return exceptions_get_exception();
1394 o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1398 return exceptions_get_exception();
1404 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1406 Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1409 *******************************************************************************/
1411 void exceptions_throw_arrayindexoutofboundsexception(void)
1413 exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1417 /* exceptions_throw_arraystoreexception ****************************************
1419 Generates and throws a java.lang.ArrayStoreException for the VM.
1421 *******************************************************************************/
1423 void exceptions_throw_arraystoreexception(void)
1425 exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1429 /* exceptions_new_classcastexception *******************************************
1431 Generates a java.lang.ClassCastException for the JIT compiler.
1433 *******************************************************************************/
1435 java_handle_t *exceptions_new_classcastexception(java_handle_t *o)
1441 LLNI_class_get(o, c);
1443 classname = c->name;
1445 e = exceptions_new_utf_utf(utf_java_lang_ClassCastException, classname);
1451 /* exceptions_throw_clonenotsupportedexception *********************************
1453 Generates and throws a java.lang.CloneNotSupportedException for the
1456 *******************************************************************************/
1458 void exceptions_throw_clonenotsupportedexception(void)
1460 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1464 /* exceptions_throw_illegalaccessexception *************************************
1466 Generates and throws a java.lang.IllegalAccessException for the VM.
1468 *******************************************************************************/
1470 void exceptions_throw_illegalaccessexception(utf *message)
1472 exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
1476 /* exceptions_throw_illegalargumentexception ***********************************
1478 Generates and throws a java.lang.IllegalArgumentException for the
1481 *******************************************************************************/
1483 void exceptions_throw_illegalargumentexception(void)
1485 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1489 /* exceptions_throw_illegalmonitorstateexception *******************************
1491 Generates and throws a java.lang.IllegalMonitorStateException for
1494 *******************************************************************************/
1496 void exceptions_throw_illegalmonitorstateexception(void)
1498 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1502 /* exceptions_throw_instantiationexception *************************************
1504 Generates and throws a java.lang.InstantiationException for the VM.
1506 *******************************************************************************/
1508 void exceptions_throw_instantiationexception(classinfo *c)
1510 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1514 /* exceptions_throw_interruptedexception ***************************************
1516 Generates and throws a java.lang.InterruptedException for the VM.
1518 *******************************************************************************/
1520 void exceptions_throw_interruptedexception(void)
1522 exceptions_throw_utf(utf_java_lang_InterruptedException);
1526 /* exceptions_throw_invocationtargetexception **********************************
1528 Generates and throws a java.lang.reflect.InvocationTargetException
1532 cause......cause exception object
1534 *******************************************************************************/
1536 void exceptions_throw_invocationtargetexception(java_handle_t *cause)
1538 exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1543 /* exceptions_throw_negativearraysizeexception *********************************
1545 Generates and throws a java.lang.NegativeArraySizeException for the
1548 *******************************************************************************/
1550 void exceptions_throw_negativearraysizeexception(void)
1552 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1556 /* exceptions_new_nullpointerexception *****************************************
1558 Generates a java.lang.NullPointerException for the VM system.
1560 *******************************************************************************/
1562 java_handle_t *exceptions_new_nullpointerexception(void)
1566 o = exceptions_new_utf(utf_java_lang_NullPointerException);
1572 /* exceptions_throw_nullpointerexception ***************************************
1574 Generates a java.lang.NullPointerException for the VM system and
1575 throw it in the VM system.
1577 *******************************************************************************/
1579 void exceptions_throw_nullpointerexception(void)
1581 exceptions_throw_utf(utf_java_lang_NullPointerException);
1585 /* exceptions_throw_privilegedactionexception **********************************
1587 Generates and throws a java.security.PrivilegedActionException.
1589 *******************************************************************************/
1591 void exceptions_throw_privilegedactionexception(java_handle_t *exception)
1593 exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
1598 /* exceptions_throw_stringindexoutofboundsexception ****************************
1600 Generates and throws a java.lang.StringIndexOutOfBoundsException
1603 *******************************************************************************/
1605 void exceptions_throw_stringindexoutofboundsexception(void)
1607 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1611 /* exceptions_fillinstacktrace *************************************************
1613 Calls the fillInStackTrace-method of the currently thrown
1616 *******************************************************************************/
1618 java_handle_t *exceptions_fillinstacktrace(void)
1626 o = exceptions_get_and_clear_exception();
1630 /* resolve methodinfo pointer from exception object */
1632 LLNI_class_get(o, c);
1634 #if defined(ENABLE_JAVASE)
1635 m = class_resolvemethod(c,
1636 utf_fillInStackTrace,
1637 utf_void__java_lang_Throwable);
1638 #elif defined(ENABLE_JAVAME_CLDC1_1)
1639 m = class_resolvemethod(c,
1640 utf_fillInStackTrace,
1643 #error IMPLEMENT ME!
1648 (void) vm_call_method(m, o);
1650 /* return exception object */
1656 /* exceptions_handle_exception *************************************************
1658 Try to find an exception handler for the given exception and return it.
1659 If no handler is found, exit the monitor of the method (if any)
1663 xptr.........the exception object
1664 xpc..........PC of where the exception was thrown
1665 pv...........Procedure Value of the current method
1666 sp...........current stack pointer
1669 the address of the first matching exception handler, or
1670 NULL if no handler was found
1672 *******************************************************************************/
1674 #if defined(ENABLE_JIT)
1675 void *exceptions_handle_exception(java_object_t *xptro, void *xpc, void *pv, void *sp)
1677 stackframeinfo_t sfi;
1678 java_handle_t *xptr;
1681 exceptiontable_t *et;
1682 exceptiontable_entry_t *ete;
1684 classref_or_classinfo cr;
1686 #if defined(ENABLE_THREADS)
1692 /* Addresses are 31 bit integers */
1693 # define ADDR_MASK(x) (void *) ((uintptr_t) (x) & 0x7FFFFFFF)
1695 # define ADDR_MASK(x) (x)
1698 xptr = LLNI_WRAP(xptro);
1699 xpc = ADDR_MASK(xpc);
1701 /* Fill and add a stackframeinfo (XPC is equal to RA). */
1703 stacktrace_stackframeinfo_add(&sfi, pv, sp, xpc, xpc);
1707 /* Get the codeinfo for the current method. */
1709 code = code_get_codeinfo_for_pv(pv);
1711 /* Get the methodinfo pointer from the codeinfo pointer. For
1712 asm_vm_call_method the codeinfo pointer is NULL and we simply
1713 can return the proper exception handler. */
1716 result = (void *) (uintptr_t) &asm_vm_call_method_exception_handler;
1717 goto exceptions_handle_exception_return;
1722 #if !defined(NDEBUG)
1723 /* print exception trace */
1725 if (opt_TraceExceptions)
1726 trace_exception(LLNI_DIRECT(xptr), m, xpc);
1728 # if defined(ENABLE_VMLOG)
1729 vmlog_cacao_throw(xptr);
1733 /* Get the exception table. */
1735 et = code->exceptiontable;
1738 /* Iterate over all exception table entries. */
1742 for (i = 0; i < et->length; i++, ete++) {
1743 /* is the xpc is the current catch range */
1745 if ((ADDR_MASK(ete->startpc) <= xpc) && (xpc < ADDR_MASK(ete->endpc))) {
1746 cr = ete->catchtype;
1748 /* NULL catches everything */
1750 if (cr.any == NULL) {
1751 #if !defined(NDEBUG)
1752 /* Print stacktrace of exception when caught. */
1754 # if defined(ENABLE_VMLOG)
1755 vmlog_cacao_catch(xptr);
1758 if (opt_TraceExceptions) {
1759 exceptions_print_exception(xptr);
1760 stacktrace_print_exception(xptr);
1764 result = ete->handlerpc;
1765 goto exceptions_handle_exception_return;
1768 /* resolve or load/link the exception class */
1770 if (IS_CLASSREF(cr)) {
1771 /* The exception class reference is unresolved. */
1772 /* We have to do _eager_ resolving here. While the
1773 class of the exception object is guaranteed to be
1774 loaded, it may well have been loaded by a different
1775 loader than the defining loader of m's class, which
1776 is the one we must use to resolve the catch
1777 class. Thus lazy resolving might fail, even if the
1778 result of the resolution would be an already loaded
1781 c = resolve_classref_eager(cr.ref);
1784 /* Exception resolving the exception class, argh! */
1785 goto exceptions_handle_exception_return;
1788 /* Ok, we resolved it. Enter it in the table, so we
1789 don't have to do this again. */
1790 /* XXX this write should be atomic. Is it? */
1792 ete->catchtype.cls = c;
1797 /* XXX I don't think this case can ever happen. -Edwin */
1798 if (!(c->state & CLASS_LOADED))
1799 /* use the methods' classloader */
1800 if (!load_class_from_classloader(c->name,
1801 m->clazz->classloader))
1802 goto exceptions_handle_exception_return;
1804 /* XXX I think, if it is not linked, we can be sure
1805 that the exception object is no (indirect) instance
1806 of it, no? -Edwin */
1807 if (!(c->state & CLASS_LINKED))
1809 goto exceptions_handle_exception_return;
1812 /* is the thrown exception an instance of the catch class? */
1814 if (builtin_instanceof(xptr, c)) {
1815 #if !defined(NDEBUG)
1816 /* Print stacktrace of exception when caught. */
1818 # if defined(ENABLE_VMLOG)
1819 vmlog_cacao_catch(xptr);
1822 if (opt_TraceExceptions) {
1823 exceptions_print_exception(xptr);
1824 stacktrace_print_exception(xptr);
1828 result = ete->handlerpc;
1829 goto exceptions_handle_exception_return;
1835 #if defined(ENABLE_THREADS)
1836 /* Is this method realization synchronized? */
1838 if (code_is_synchronized(code)) {
1839 /* Get synchronization object. */
1841 o = *((java_object_t **) (((uintptr_t) sp) + code->synchronizedoffset));
1845 lock_monitor_exit(LLNI_QUICKWRAP(o));
1849 /* none of the exceptions catch this one */
1851 #if !defined(NDEBUG)
1852 # if defined(ENABLE_VMLOG)
1853 vmlog_cacao_unwnd_method(m);
1856 # if defined(ENABLE_DEBUG_FILTER)
1857 if (show_filters_test_verbosecall_exit(m)) {
1860 /* outdent the log message */
1862 if (opt_verbosecall) {
1863 if (TRACEJAVACALLINDENT)
1864 TRACEJAVACALLINDENT--;
1866 log_text("exceptions_handle_exception: WARNING: unmatched unindent");
1869 # if defined(ENABLE_DEBUG_FILTER)
1872 #endif /* !defined(NDEBUG) */
1876 exceptions_handle_exception_return:
1878 /* Remove the stackframeinfo. */
1880 stacktrace_stackframeinfo_remove(&sfi);
1884 #endif /* defined(ENABLE_JIT) */
1887 /* exceptions_print_exception **************************************************
1889 Prints an exception, the detail message and the cause, if
1890 available, with CACAO internal functions to stdout.
1892 *******************************************************************************/
1894 void exceptions_print_exception(java_handle_t *xptr)
1896 java_lang_Throwable jlt(xptr);
1898 if (jlt.is_null()) {
1903 #if defined(ENABLE_JAVASE)
1904 java_lang_Throwable jltcause(jlt.get_cause());
1907 /* print the root exception */
1909 classinfo* c = jlt.get_Class();
1910 utf_display_printable_ascii_classname(c->name);
1912 java_lang_String jls(jlt.get_detailMessage());
1914 if (!jls.is_null()) {
1915 utf* u = javastring_toutf(jls.get_handle(), false);
1918 utf_display_printable_ascii(u);
1923 #if defined(ENABLE_JAVASE)
1924 /* print the cause if available */
1926 // FIXME cause != t compare with operator override.
1927 if ((!jltcause.is_null()) && (jltcause.get_handle() != jlt.get_handle())) {
1928 printf("Caused by: ");
1930 c = jltcause.get_Class();
1931 utf_display_printable_ascii_classname(c->name);
1933 java_lang_String jlscause(jlt.get_detailMessage());
1935 if (jlscause.get_handle() != NULL) {
1936 utf* u = javastring_toutf(jlscause.get_handle(), false);
1939 utf_display_printable_ascii(u);
1948 /* exceptions_print_current_exception ******************************************
1950 Prints the current pending exception, the detail message and the
1951 cause, if available, with CACAO internal functions to stdout.
1953 *******************************************************************************/
1955 void exceptions_print_current_exception(void)
1959 o = exceptions_get_exception();
1961 exceptions_print_exception(o);
1965 /* exceptions_print_stacktrace *************************************************
1967 Prints a pending exception with Throwable.printStackTrace(). If
1968 there happens an exception during printStackTrace(), we print the
1969 thrown exception and the original one.
1971 NOTE: This function calls Java code.
1973 *******************************************************************************/
1975 void exceptions_print_stacktrace(void)
1982 #if defined(ENABLE_THREADS)
1984 java_lang_Thread *to;
1987 /* Get and clear exception because we are calling Java code
1990 e = exceptions_get_and_clear_exception();
1996 /* FIXME Enable me. */
1997 if (builtin_instanceof(e, class_java_lang_ThreadDeath)) {
1998 /* Don't print anything if we are being killed. */
2003 /* Get the exception class. */
2005 LLNI_class_get(e, c);
2007 /* Find the printStackTrace() method. */
2009 m = class_resolveclassmethod(c,
2010 utf_printStackTrace,
2012 class_java_lang_Object,
2016 vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
2018 /* Print message. */
2020 fprintf(stderr, "Exception ");
2022 #if defined(ENABLE_THREADS)
2023 /* Print thread name. We get the thread here explicitly as we
2024 need it afterwards. */
2026 t = thread_get_current();
2027 to = (java_lang_Thread *) thread_get_object(t);
2030 fprintf(stderr, "in thread \"");
2031 thread_fprint_name(t, stderr);
2032 fprintf(stderr, "\" ");
2036 /* Print the stacktrace. */
2038 if (builtin_instanceof(e, class_java_lang_Throwable)) {
2039 (void) vm_call_method(m, e);
2041 /* If this happens we are EXTREMLY out of memory or have a
2042 serious problem while printStackTrace. But may be
2043 another exception, so print it. */
2045 ne = exceptions_get_exception();
2048 fprintf(stderr, "Exception while printStackTrace(): ");
2050 /* Print the current exception. */
2052 exceptions_print_exception(ne);
2053 stacktrace_print_exception(ne);
2055 /* Now print the original exception. */
2057 fprintf(stderr, "Original exception was: ");
2058 exceptions_print_exception(e);
2059 stacktrace_print_exception(e);
2063 fprintf(stderr, ". Uncaught exception of type ");
2064 #if !defined(NDEBUG)
2065 /* FIXME This prints to stdout. */
2068 fprintf(stderr, "UNKNOWN");
2070 fprintf(stderr, ".");
2081 * These are local overrides for various environment variables in Emacs.
2082 * Please do not remove this and leave it at the end of the file, where
2083 * Emacs will automagically detect them.
2084 * ---------------------------------------------------------------------
2087 * indent-tabs-mode: t
2091 * vim:noexpandtab:sw=4:ts=4: