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/llni.h"
41 #include "native/native.h"
43 #include "threads/lock-common.h"
44 #include "threads/thread.hpp"
46 #include "toolbox/util.h"
48 #include "vm/jit/builtin.hpp"
50 #include "vm/exceptions.hpp"
51 #include "vm/global.h"
52 #include "vm/globals.hpp"
53 #include "vm/javaobjects.hpp"
54 #include "vm/loader.hpp"
55 #include "vm/method.h"
56 #include "vm/options.h"
58 #include "vm/string.hpp"
61 #include "vm/jit/asmpart.h"
62 #include "vm/jit/jit.hpp"
63 #include "vm/jit/methodheader.h"
64 #include "vm/jit/patcher-common.hpp"
65 #include "vm/jit/show.hpp"
66 #include "vm/jit/stacktrace.hpp"
67 #include "vm/jit/trace.hpp"
69 #if defined(ENABLE_VMLOG)
70 #include <vmlog_cacao.h>
77 /* for raising exceptions from native methods *********************************/
79 #if !defined(ENABLE_THREADS)
80 java_object_t *_no_threads_exceptionptr = NULL;
84 /* exceptions_get_exception ****************************************************
86 Returns the current exception pointer of the current thread.
88 *******************************************************************************/
90 java_handle_t *exceptions_get_exception(void)
94 #if defined(ENABLE_THREADS)
100 /* Get the exception. */
104 #if defined(ENABLE_THREADS)
105 o = t->_exceptionptr;
107 o = _no_threads_exceptionptr;
114 /* Return the exception. */
120 /* exceptions_set_exception ****************************************************
122 Sets the exception pointer of the current thread.
124 *******************************************************************************/
126 void exceptions_set_exception(java_handle_t *e)
131 #if defined(ENABLE_THREADS)
137 /* Set the exception. */
144 if (opt_DebugExceptions) {
145 printf("[exceptions_set_exception : t=%p, o=%p, class=",
146 (void *) t, (void *) o);
147 class_print(o->vftbl->clazz);
152 #if defined(ENABLE_THREADS)
153 t->_exceptionptr = o;
155 _no_threads_exceptionptr = o;
162 /* exceptions_clear_exception **************************************************
164 Clears the current exception pointer of the current thread.
166 *******************************************************************************/
168 void exceptions_clear_exception(void)
172 #if defined(ENABLE_THREADS)
178 /* Set the exception. */
181 if (opt_DebugExceptions) {
182 printf("[exceptions_clear_exception: t=%p]\n", (void *) t);
186 #if defined(ENABLE_THREADS)
187 t->_exceptionptr = NULL;
189 _no_threads_exceptionptr = NULL;
194 /* exceptions_get_and_clear_exception ******************************************
196 Gets the exception pointer of the current thread and clears it.
197 This function may return NULL.
199 *******************************************************************************/
201 java_handle_t *exceptions_get_and_clear_exception(void)
205 /* Get the exception... */
207 o = exceptions_get_exception();
209 /* ...and clear the exception if it is set. */
212 exceptions_clear_exception();
214 /* return the exception */
220 /* exceptions_abort ************************************************************
222 Prints exception to be thrown and aborts.
225 classname....class name
226 message......exception message
228 *******************************************************************************/
230 static void exceptions_abort(utf *classname, utf *message)
232 log_println("exception thrown while VM is initializing: ");
235 utf_display_printable_ascii_classname(classname);
237 if (message != NULL) {
239 utf_display_printable_ascii_classname(message);
244 VM::get_current()->abort("Aborting...");
248 /* exceptions_new_class_utf ****************************************************
250 Creates an exception object with the given class and initalizes it
251 with the given utf message.
254 c ......... exception class
255 message ... the message as an utf *
258 an exception pointer (in any case -- either it is the newly
259 created exception, or an exception thrown while trying to create
262 *******************************************************************************/
264 static java_handle_t *exceptions_new_class_utf(classinfo *c, utf *message)
269 if (VM::get_current()->is_initializing()) {
270 /* This can happen when global class variables are used which
271 are not initialized yet. */
274 exceptions_abort(NULL, message);
276 exceptions_abort(c->name, message);
279 s = javastring_new(message);
282 return exceptions_get_exception();
284 o = native_new_and_init_string(c, s);
287 return exceptions_get_exception();
293 /* exceptions_new_utf **********************************************************
295 Creates an exception object with the given name and initalizes it.
298 classname....class name in UTF-8
300 *******************************************************************************/
302 static java_handle_t *exceptions_new_utf(utf *classname)
307 if (VM::get_current()->is_initializing())
308 exceptions_abort(classname, NULL);
310 c = load_class_bootstrap(classname);
313 return exceptions_get_exception();
315 o = native_new_and_init(c);
318 return exceptions_get_exception();
324 /* exceptions_new_utf_javastring ***********************************************
326 Creates an exception object with the given name and initalizes it
327 with the given java/lang/String message.
330 classname....class name in UTF-8
331 message......the message as a java.lang.String
334 an exception pointer (in any case -- either it is the newly created
335 exception, or an exception thrown while trying to create it).
337 *******************************************************************************/
339 static java_handle_t *exceptions_new_utf_javastring(utf *classname,
340 java_handle_t *message)
345 if (VM::get_current()->is_initializing())
346 exceptions_abort(classname, NULL);
348 c = load_class_bootstrap(classname);
351 return exceptions_get_exception();
353 o = native_new_and_init_string(c, message);
356 return exceptions_get_exception();
362 /* exceptions_new_utf_utf ******************************************************
364 Creates an exception object with the given name and initalizes it
365 with the given utf message.
368 classname....class name in UTF-8
369 message......the message as an utf *
372 an exception pointer (in any case -- either it is the newly created
373 exception, or an exception thrown while trying to create it).
375 *******************************************************************************/
377 static java_handle_t *exceptions_new_utf_utf(utf *classname, utf *message)
382 if (VM::get_current()->is_initializing())
383 exceptions_abort(classname, message);
385 c = load_class_bootstrap(classname);
388 return exceptions_get_exception();
390 o = exceptions_new_class_utf(c, message);
396 /* exceptions_throw_class_utf **************************************************
398 Creates an exception object with the given class, initalizes and
399 throws it with the given utf message.
402 c ......... exception class
403 message ... the message as an utf *
405 *******************************************************************************/
407 static void exceptions_throw_class_utf(classinfo *c, utf *message)
411 o = exceptions_new_class_utf(c, message);
413 exceptions_set_exception(o);
417 /* exceptions_throw_utf ********************************************************
419 Creates an exception object with the given name, initalizes and
423 classname....class name in UTF-8
425 *******************************************************************************/
427 static void exceptions_throw_utf(utf *classname)
431 o = exceptions_new_utf(classname);
436 exceptions_set_exception(o);
440 /* exceptions_throw_utf_throwable **********************************************
442 Creates an exception object with the given name and initalizes it
443 with the given java/lang/Throwable exception.
446 classname....class name in UTF-8
447 cause........the given Throwable
449 *******************************************************************************/
451 static void exceptions_throw_utf_throwable(utf *classname,
452 java_handle_t *cause)
457 if (VM::get_current()->is_initializing())
458 exceptions_abort(classname, NULL);
460 java_lang_Throwable jlt(cause);
462 c = load_class_bootstrap(classname);
469 java_handle_t* h = builtin_new(c);
474 /* call initializer */
476 m = class_resolveclassmethod(c,
478 utf_java_lang_Throwable__void,
485 (void) vm_call_method(m, h, jlt.get_handle());
487 exceptions_set_exception(h);
491 /* exceptions_throw_utf_exception **********************************************
493 Creates an exception object with the given name and initalizes it
494 with the given java/lang/Exception exception.
497 classname....class name in UTF-8
498 exception....the given Exception
500 *******************************************************************************/
502 static void exceptions_throw_utf_exception(utf *classname,
503 java_handle_t *exception)
509 if (VM::get_current()->is_initializing())
510 exceptions_abort(classname, NULL);
512 c = load_class_bootstrap(classname);
524 /* call initializer */
526 m = class_resolveclassmethod(c,
528 utf_java_lang_Exception__V,
535 (void) vm_call_method(m, o, exception);
537 exceptions_set_exception(o);
541 /* exceptions_throw_utf_cause **************************************************
543 Creates an exception object with the given name and initalizes it
544 with the given java/lang/Throwable exception with initCause.
547 classname....class name in UTF-8
548 cause........the given Throwable
550 *******************************************************************************/
552 static void exceptions_throw_utf_cause(utf *classname, java_handle_t *cause)
554 if (VM::get_current()->is_initializing())
555 exceptions_abort(classname, NULL);
557 java_lang_Throwable jltcause(cause);
559 classinfo* c = load_class_bootstrap(classname);
566 java_handle_t* h = builtin_new(c);
571 /* call initializer */
573 methodinfo* m = class_resolveclassmethod(c,
575 utf_java_lang_String__void,
582 (void) vm_call_method(m, h, jltcause.get_detailMessage());
586 m = class_resolveclassmethod(c,
588 utf_java_lang_Throwable__java_lang_Throwable,
595 (void) vm_call_method(m, h, jltcause.get_handle());
597 exceptions_set_exception(h);
601 /* exceptions_throw_utf_utf ****************************************************
603 Creates an exception object with the given name, initalizes and
604 throws it with the given utf message.
607 classname....class name in UTF-8
608 message......the message as an utf *
610 *******************************************************************************/
612 static void exceptions_throw_utf_utf(utf *classname, utf *message)
616 o = exceptions_new_utf_utf(classname, message);
618 exceptions_set_exception(o);
622 /* exceptions_new_abstractmethoderror ****************************************
624 Generates a java.lang.AbstractMethodError for the VM.
626 *******************************************************************************/
628 java_handle_t *exceptions_new_abstractmethoderror(void)
632 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
638 /* exceptions_new_error ********************************************************
640 Generates a java.lang.Error for the VM.
642 *******************************************************************************/
644 #if defined(ENABLE_JAVAME_CLDC1_1)
645 static java_handle_t *exceptions_new_error(utf *message)
649 o = exceptions_new_utf_utf(utf_java_lang_Error, message);
656 /* exceptions_asm_new_abstractmethoderror **************************************
658 Generates a java.lang.AbstractMethodError for
659 asm_abstractmethoderror.
661 *******************************************************************************/
663 java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
665 stackframeinfo_t sfi;
669 /* Fill and add a stackframeinfo (XPC is equal to RA). */
671 stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra);
673 /* create the exception */
675 #if defined(ENABLE_JAVASE)
676 e = exceptions_new_abstractmethoderror();
678 e = exceptions_new_error(utf_java_lang_AbstractMethodError);
681 /* Remove the stackframeinfo. */
683 stacktrace_stackframeinfo_remove(&sfi);
685 /* unwrap the exception */
686 /* ATTENTION: do the this _after_ the stackframeinfo was removed */
694 /* exceptions_new_arraystoreexception ******************************************
696 Generates a java.lang.ArrayStoreException for the VM.
698 *******************************************************************************/
700 java_handle_t *exceptions_new_arraystoreexception(void)
704 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
710 /* exceptions_throw_abstractmethoderror ****************************************
712 Generates and throws a java.lang.AbstractMethodError for the VM.
714 *******************************************************************************/
716 void exceptions_throw_abstractmethoderror(void)
718 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
722 /* exceptions_throw_classcircularityerror **************************************
724 Generates and throws a java.lang.ClassCircularityError for the
728 c....the class in which the error was found
730 *******************************************************************************/
732 void exceptions_throw_classcircularityerror(classinfo *c)
734 exceptions_throw_utf_utf(utf_java_lang_ClassCircularityError, c->name);
738 /* exceptions_throw_classformaterror *******************************************
740 Generates and throws a java.lang.ClassFormatError for the VM.
743 c............the class in which the error was found
744 message......UTF-8 format string
746 *******************************************************************************/
748 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
755 /* calculate message length */
760 msglen += utf_bytes(c->name) + strlen(" (");
762 va_start(ap, message);
763 msglen += get_variable_message_length(message, ap);
767 msglen += strlen(")");
769 msglen += strlen("0");
771 /* allocate a buffer */
773 msg = MNEW(char, msglen);
775 /* print message into allocated buffer */
778 utf_copy_classname(msg, c->name);
782 va_start(ap, message);
783 vsprintf(msg + strlen(msg), message, ap);
789 u = utf_new_char(msg);
793 MFREE(msg, char, msglen);
795 /* throw exception */
797 exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
801 /* exceptions_throw_classnotfoundexception *************************************
803 Generates and throws a java.lang.ClassNotFoundException for the
807 name.........name of the class not found as a utf *
809 *******************************************************************************/
811 void exceptions_throw_classnotfoundexception(utf *name)
813 exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
817 /* exceptions_throw_noclassdeffounderror ***************************************
819 Generates and throws a java.lang.NoClassDefFoundError.
822 name.........name of the class not found as a utf *
824 *******************************************************************************/
826 void exceptions_throw_noclassdeffounderror(utf *name)
828 exceptions_throw_utf_utf(utf_java_lang_NoClassDefFoundError, name);
832 /* exceptions_throw_noclassdeffounderror_cause *********************************
834 Generates and throws a java.lang.NoClassDefFoundError with the
837 *******************************************************************************/
839 void exceptions_throw_noclassdeffounderror_cause(java_handle_t *cause)
841 exceptions_throw_utf_cause(utf_java_lang_NoClassDefFoundError, cause);
845 /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
847 Generates and throws a java.lang.NoClassDefFoundError with a
851 name.........name of the class not found as a utf *
853 *******************************************************************************/
855 void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
861 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
862 utf_bytes(name) + strlen(")") + strlen("0");
864 msg = MNEW(char, msglen);
866 utf_copy_classname(msg, c->name);
867 strcat(msg, " (wrong name: ");
868 utf_cat_classname(msg, name);
871 u = utf_new_char(msg);
873 MFREE(msg, char, msglen);
875 exceptions_throw_noclassdeffounderror(u);
879 /* exceptions_throw_exceptionininitializererror ********************************
881 Generates and throws a java.lang.ExceptionInInitializerError for
885 cause......cause exception object
887 *******************************************************************************/
889 void exceptions_throw_exceptionininitializererror(java_handle_t *cause)
891 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
896 /* exceptions_throw_incompatibleclasschangeerror *******************************
898 Generates and throws a java.lang.IncompatibleClassChangeError for
902 message......UTF-8 message format string
904 *******************************************************************************/
906 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
912 /* calculate exception message length */
914 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
916 /* allocate memory */
918 msg = MNEW(char, msglen);
920 utf_copy_classname(msg, c->name);
921 strcat(msg, message);
923 u = utf_new_char(msg);
927 MFREE(msg, char, msglen);
929 /* throw exception */
931 exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
935 /* exceptions_throw_instantiationerror *****************************************
937 Generates and throws a java.lang.InstantiationError for the VM.
939 *******************************************************************************/
941 void exceptions_throw_instantiationerror(classinfo *c)
943 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
947 /* exceptions_throw_internalerror **********************************************
949 Generates and throws a java.lang.InternalError for the VM.
952 message......UTF-8 message format string
954 *******************************************************************************/
956 void exceptions_throw_internalerror(const char *message, ...)
963 /* calculate exception message length */
965 va_start(ap, message);
966 msglen = get_variable_message_length(message, ap);
969 /* allocate memory */
971 msg = MNEW(char, msglen);
973 /* generate message */
975 va_start(ap, message);
976 vsprintf(msg, message, ap);
979 u = utf_new_char(msg);
983 MFREE(msg, char, msglen);
985 /* throw exception */
987 exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
991 /* exceptions_throw_linkageerror ***********************************************
993 Generates and throws java.lang.LinkageError with an error message.
996 message......UTF-8 message
997 c............class related to the error. If this is != NULL
998 the name of c is appended to the error message.
1000 *******************************************************************************/
1002 void exceptions_throw_linkageerror(const char *message, classinfo *c)
1008 /* calculate exception message length */
1010 len = strlen(message) + 1;
1013 len += utf_bytes(c->name);
1015 /* allocate memory */
1017 msg = MNEW(char, len);
1019 /* generate message */
1021 strcpy(msg, message);
1024 utf_cat_classname(msg, c->name);
1026 u = utf_new_char(msg);
1030 MFREE(msg, char, len);
1032 exceptions_throw_utf_utf(utf_java_lang_LinkageError, u);
1036 /* exceptions_throw_nosuchfielderror *******************************************
1038 Generates and throws a java.lang.NoSuchFieldError with an error
1042 c............class in which the field was not found
1043 name.........name of the field
1045 *******************************************************************************/
1047 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
1053 /* calculate exception message length */
1055 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
1057 /* allocate memory */
1059 msg = MNEW(char, msglen);
1061 /* generate message */
1063 utf_copy_classname(msg, c->name);
1067 u = utf_new_char(msg);
1071 MFREE(msg, char, msglen);
1073 exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
1077 /* exceptions_throw_nosuchmethoderror ******************************************
1079 Generates and throws a java.lang.NoSuchMethodError with an error
1083 c............class in which the method was not found
1084 name.........name of the method
1085 desc.........descriptor of the method
1087 *******************************************************************************/
1089 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
1095 /* calculate exception message length */
1097 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
1098 utf_bytes(desc) + strlen("0");
1100 /* allocate memory */
1102 msg = MNEW(char, msglen);
1104 /* generate message */
1106 utf_copy_classname(msg, c->name);
1111 u = utf_new_char(msg);
1115 MFREE(msg, char, msglen);
1117 #if defined(ENABLE_JAVASE)
1118 exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
1120 exceptions_throw_utf_utf(utf_java_lang_Error, u);
1125 /* exceptions_throw_outofmemoryerror *******************************************
1127 Generates and throws an java.lang.OutOfMemoryError for the VM.
1129 *******************************************************************************/
1131 void exceptions_throw_outofmemoryerror(void)
1133 exceptions_throw_utf(utf_java_lang_OutOfMemoryError);
1137 /* exceptions_throw_unsatisfiedlinkerror ***************************************
1139 Generates and throws a java.lang.UnsatisfiedLinkError for the
1143 name......UTF-8 name string
1145 *******************************************************************************/
1147 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1149 #if defined(ENABLE_JAVASE)
1150 exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1152 exceptions_throw_utf_utf(utf_java_lang_Error, name);
1157 /* exceptions_throw_unsupportedclassversionerror *******************************
1159 Generates and throws a java.lang.UnsupportedClassVersionError for
1163 c............class in which the method was not found
1164 message......UTF-8 format string
1166 *******************************************************************************/
1168 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1174 /* calculate exception message length */
1177 utf_bytes(c->name) +
1178 strlen(" (Unsupported major.minor version 00.0)") +
1181 /* allocate memory */
1183 msg = MNEW(char, msglen);
1185 /* generate message */
1187 utf_copy_classname(msg, c->name);
1188 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1191 u = utf_new_char(msg);
1195 MFREE(msg, char, msglen);
1197 /* throw exception */
1199 exceptions_throw_utf_utf(utf_java_lang_UnsupportedClassVersionError, u);
1203 /* exceptions_throw_verifyerror ************************************************
1205 Generates and throws a java.lang.VerifyError for the JIT compiler.
1208 m............method in which the error was found
1209 message......UTF-8 format string
1211 *******************************************************************************/
1213 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1220 /* calculate exception message length */
1226 strlen("(class: ") + utf_bytes(m->clazz->name) +
1227 strlen(", method: ") + utf_bytes(m->name) +
1228 strlen(" signature: ") + utf_bytes(m->descriptor) +
1229 strlen(") ") + strlen("0");
1231 va_start(ap, message);
1232 msglen += get_variable_message_length(message, ap);
1235 /* allocate memory */
1237 msg = MNEW(char, msglen);
1239 /* generate message */
1242 strcpy(msg, "(class: ");
1243 utf_cat_classname(msg, m->clazz->name);
1244 strcat(msg, ", method: ");
1245 utf_cat(msg, m->name);
1246 strcat(msg, " signature: ");
1247 utf_cat(msg, m->descriptor);
1251 va_start(ap, message);
1252 vsprintf(msg + strlen(msg), message, ap);
1255 u = utf_new_char(msg);
1259 MFREE(msg, char, msglen);
1261 /* throw exception */
1263 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1267 /* exceptions_throw_verifyerror_for_stack **************************************
1269 throws a java.lang.VerifyError for an invalid stack slot type
1272 m............method in which the error was found
1273 type.........the expected type
1276 an exception pointer (in any case -- either it is the newly created
1277 exception, or an exception thrown while trying to create it).
1279 *******************************************************************************/
1281 void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
1287 /* calculate exception message length */
1292 msglen = strlen("(class: ") + utf_bytes(m->clazz->name) +
1293 strlen(", method: ") + utf_bytes(m->name) +
1294 strlen(" signature: ") + utf_bytes(m->descriptor) +
1295 strlen(") Expecting to find longest-------typename on stack")
1298 /* allocate memory */
1300 msg = MNEW(char, msglen);
1302 /* generate message */
1305 strcpy(msg, "(class: ");
1306 utf_cat_classname(msg, m->clazz->name);
1307 strcat(msg, ", method: ");
1308 utf_cat(msg, m->name);
1309 strcat(msg, " signature: ");
1310 utf_cat(msg, m->descriptor);
1317 strcat(msg, "Expecting to find ");
1322 case TYPE_INT: name = "integer"; break;
1323 case TYPE_LNG: name = "long"; break;
1324 case TYPE_FLT: name = "float"; break;
1325 case TYPE_DBL: name = "double"; break;
1326 case TYPE_ADR: name = "object/array"; break;
1327 case TYPE_RET: name = "returnAddress"; break;
1328 default: name = "<INVALID>"; assert(0); break;
1332 strcat(msg, " on stack");
1334 u = utf_new_char(msg);
1338 MFREE(msg, char, msglen);
1340 /* throw exception */
1342 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1346 /* exceptions_new_arithmeticexception ******************************************
1348 Generates a java.lang.ArithmeticException for the JIT compiler.
1350 *******************************************************************************/
1352 java_handle_t *exceptions_new_arithmeticexception(void)
1356 o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
1357 utf_division_by_zero);
1363 /* exceptions_new_arrayindexoutofboundsexception *******************************
1365 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1368 *******************************************************************************/
1370 java_handle_t *exceptions_new_arrayindexoutofboundsexception(s4 index)
1376 /* convert the index into a String, like Sun does */
1378 m = class_resolveclassmethod(class_java_lang_String,
1379 utf_new_char("valueOf"),
1380 utf_new_char("(I)Ljava/lang/String;"),
1381 class_java_lang_Object,
1385 return exceptions_get_exception();
1387 s = vm_call_method(m, NULL, index);
1390 return exceptions_get_exception();
1392 o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1396 return exceptions_get_exception();
1402 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1404 Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1407 *******************************************************************************/
1409 void exceptions_throw_arrayindexoutofboundsexception(void)
1411 exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1415 /* exceptions_throw_arraystoreexception ****************************************
1417 Generates and throws a java.lang.ArrayStoreException for the VM.
1419 *******************************************************************************/
1421 void exceptions_throw_arraystoreexception(void)
1423 exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1427 /* exceptions_new_classcastexception *******************************************
1429 Generates a java.lang.ClassCastException for the JIT compiler.
1431 *******************************************************************************/
1433 java_handle_t *exceptions_new_classcastexception(java_handle_t *o)
1439 LLNI_class_get(o, c);
1441 classname = c->name;
1443 e = exceptions_new_utf_utf(utf_java_lang_ClassCastException, classname);
1449 /* exceptions_throw_clonenotsupportedexception *********************************
1451 Generates and throws a java.lang.CloneNotSupportedException for the
1454 *******************************************************************************/
1456 void exceptions_throw_clonenotsupportedexception(void)
1458 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1462 /* exceptions_throw_illegalaccessexception *************************************
1464 Generates and throws a java.lang.IllegalAccessException for the VM.
1466 *******************************************************************************/
1468 void exceptions_throw_illegalaccessexception(utf *message)
1470 exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
1474 /* exceptions_throw_illegalargumentexception ***********************************
1476 Generates and throws a java.lang.IllegalArgumentException for the
1479 *******************************************************************************/
1481 void exceptions_throw_illegalargumentexception(void)
1483 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1487 /* exceptions_throw_illegalmonitorstateexception *******************************
1489 Generates and throws a java.lang.IllegalMonitorStateException for
1492 *******************************************************************************/
1494 void exceptions_throw_illegalmonitorstateexception(void)
1496 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1500 /* exceptions_throw_instantiationexception *************************************
1502 Generates and throws a java.lang.InstantiationException for the VM.
1504 *******************************************************************************/
1506 void exceptions_throw_instantiationexception(classinfo *c)
1508 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1512 /* exceptions_throw_interruptedexception ***************************************
1514 Generates and throws a java.lang.InterruptedException for the VM.
1516 *******************************************************************************/
1518 void exceptions_throw_interruptedexception(void)
1520 exceptions_throw_utf(utf_java_lang_InterruptedException);
1524 /* exceptions_throw_invocationtargetexception **********************************
1526 Generates and throws a java.lang.reflect.InvocationTargetException
1530 cause......cause exception object
1532 *******************************************************************************/
1534 void exceptions_throw_invocationtargetexception(java_handle_t *cause)
1536 exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1541 /* exceptions_throw_negativearraysizeexception *********************************
1543 Generates and throws a java.lang.NegativeArraySizeException for the
1546 *******************************************************************************/
1548 void exceptions_throw_negativearraysizeexception(void)
1550 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1554 /* exceptions_new_nullpointerexception *****************************************
1556 Generates a java.lang.NullPointerException for the VM system.
1558 *******************************************************************************/
1560 java_handle_t *exceptions_new_nullpointerexception(void)
1564 o = exceptions_new_utf(utf_java_lang_NullPointerException);
1570 /* exceptions_throw_nullpointerexception ***************************************
1572 Generates a java.lang.NullPointerException for the VM system and
1573 throw it in the VM system.
1575 *******************************************************************************/
1577 void exceptions_throw_nullpointerexception(void)
1579 exceptions_throw_utf(utf_java_lang_NullPointerException);
1583 /* exceptions_throw_privilegedactionexception **********************************
1585 Generates and throws a java.security.PrivilegedActionException.
1587 *******************************************************************************/
1589 void exceptions_throw_privilegedactionexception(java_handle_t *exception)
1591 exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
1596 /* exceptions_throw_stringindexoutofboundsexception ****************************
1598 Generates and throws a java.lang.StringIndexOutOfBoundsException
1601 *******************************************************************************/
1603 void exceptions_throw_stringindexoutofboundsexception(void)
1605 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1609 /* exceptions_fillinstacktrace *************************************************
1611 Calls the fillInStackTrace-method of the currently thrown
1614 *******************************************************************************/
1616 java_handle_t *exceptions_fillinstacktrace(void)
1624 o = exceptions_get_and_clear_exception();
1628 /* resolve methodinfo pointer from exception object */
1630 LLNI_class_get(o, c);
1632 #if defined(ENABLE_JAVASE)
1633 m = class_resolvemethod(c,
1634 utf_fillInStackTrace,
1635 utf_void__java_lang_Throwable);
1636 #elif defined(ENABLE_JAVAME_CLDC1_1)
1637 m = class_resolvemethod(c,
1638 utf_fillInStackTrace,
1641 #error IMPLEMENT ME!
1646 (void) vm_call_method(m, o);
1648 /* return exception object */
1654 /* exceptions_handle_exception *************************************************
1656 Try to find an exception handler for the given exception and return it.
1657 If no handler is found, exit the monitor of the method (if any)
1661 xptr.........the exception object
1662 xpc..........PC of where the exception was thrown
1663 pv...........Procedure Value of the current method
1664 sp...........current stack pointer
1667 the address of the first matching exception handler, or
1668 NULL if no handler was found
1670 *******************************************************************************/
1672 #if defined(ENABLE_JIT)
1673 void *exceptions_handle_exception(java_object_t *xptro, void *xpc, void *pv, void *sp)
1675 stackframeinfo_t sfi;
1676 java_handle_t *xptr;
1679 exceptiontable_t *et;
1680 exceptiontable_entry_t *ete;
1682 classref_or_classinfo cr;
1684 #if defined(ENABLE_THREADS)
1690 /* Addresses are 31 bit integers */
1691 # define ADDR_MASK(x) (void *) ((uintptr_t) (x) & 0x7FFFFFFF)
1693 # define ADDR_MASK(x) (x)
1696 xptr = LLNI_WRAP(xptro);
1697 xpc = ADDR_MASK(xpc);
1699 /* Fill and add a stackframeinfo (XPC is equal to RA). */
1701 stacktrace_stackframeinfo_add(&sfi, pv, sp, xpc, xpc);
1705 /* Get the codeinfo for the current method. */
1707 code = code_get_codeinfo_for_pv(pv);
1709 /* Get the methodinfo pointer from the codeinfo pointer. For
1710 asm_vm_call_method the codeinfo pointer is NULL and we simply
1711 can return the proper exception handler. */
1714 result = (void *) (uintptr_t) &asm_vm_call_method_exception_handler;
1715 goto exceptions_handle_exception_return;
1720 #if !defined(NDEBUG)
1721 /* print exception trace */
1723 if (opt_TraceExceptions)
1724 trace_exception(LLNI_DIRECT(xptr), m, xpc);
1726 # if defined(ENABLE_VMLOG)
1727 vmlog_cacao_throw(xptr);
1731 /* Get the exception table. */
1733 et = code->exceptiontable;
1736 /* Iterate over all exception table entries. */
1740 for (i = 0; i < et->length; i++, ete++) {
1741 /* is the xpc is the current catch range */
1743 if ((ADDR_MASK(ete->startpc) <= xpc) && (xpc < ADDR_MASK(ete->endpc))) {
1744 cr = ete->catchtype;
1746 /* NULL catches everything */
1748 if (cr.any == NULL) {
1749 #if !defined(NDEBUG)
1750 /* Print stacktrace of exception when caught. */
1752 # if defined(ENABLE_VMLOG)
1753 vmlog_cacao_catch(xptr);
1756 if (opt_TraceExceptions) {
1757 exceptions_print_exception(xptr);
1758 stacktrace_print_exception(xptr);
1762 result = ete->handlerpc;
1763 goto exceptions_handle_exception_return;
1766 /* resolve or load/link the exception class */
1768 if (IS_CLASSREF(cr)) {
1769 /* The exception class reference is unresolved. */
1770 /* We have to do _eager_ resolving here. While the
1771 class of the exception object is guaranteed to be
1772 loaded, it may well have been loaded by a different
1773 loader than the defining loader of m's class, which
1774 is the one we must use to resolve the catch
1775 class. Thus lazy resolving might fail, even if the
1776 result of the resolution would be an already loaded
1779 c = resolve_classref_eager(cr.ref);
1782 /* Exception resolving the exception class, argh! */
1783 goto exceptions_handle_exception_return;
1786 /* Ok, we resolved it. Enter it in the table, so we
1787 don't have to do this again. */
1788 /* XXX this write should be atomic. Is it? */
1790 ete->catchtype.cls = c;
1795 /* XXX I don't think this case can ever happen. -Edwin */
1796 if (!(c->state & CLASS_LOADED))
1797 /* use the methods' classloader */
1798 if (!load_class_from_classloader(c->name,
1799 m->clazz->classloader))
1800 goto exceptions_handle_exception_return;
1802 /* XXX I think, if it is not linked, we can be sure
1803 that the exception object is no (indirect) instance
1804 of it, no? -Edwin */
1805 if (!(c->state & CLASS_LINKED))
1807 goto exceptions_handle_exception_return;
1810 /* is the thrown exception an instance of the catch class? */
1812 if (builtin_instanceof(xptr, c)) {
1813 #if !defined(NDEBUG)
1814 /* Print stacktrace of exception when caught. */
1816 # if defined(ENABLE_VMLOG)
1817 vmlog_cacao_catch(xptr);
1820 if (opt_TraceExceptions) {
1821 exceptions_print_exception(xptr);
1822 stacktrace_print_exception(xptr);
1826 result = ete->handlerpc;
1827 goto exceptions_handle_exception_return;
1833 #if defined(ENABLE_THREADS)
1834 /* Is this method realization synchronized? */
1836 if (code_is_synchronized(code)) {
1837 /* Get synchronization object. */
1839 o = *((java_object_t **) (((uintptr_t) sp) + code->synchronizedoffset));
1843 lock_monitor_exit(LLNI_QUICKWRAP(o));
1847 /* none of the exceptions catch this one */
1849 #if !defined(NDEBUG)
1850 # if defined(ENABLE_VMLOG)
1851 vmlog_cacao_unwnd_method(m);
1854 # if defined(ENABLE_DEBUG_FILTER)
1855 if (show_filters_test_verbosecall_exit(m)) {
1858 /* outdent the log message */
1860 if (opt_verbosecall) {
1861 if (TRACEJAVACALLINDENT)
1862 TRACEJAVACALLINDENT--;
1864 log_text("exceptions_handle_exception: WARNING: unmatched unindent");
1867 # if defined(ENABLE_DEBUG_FILTER)
1870 #endif /* !defined(NDEBUG) */
1874 exceptions_handle_exception_return:
1876 /* Remove the stackframeinfo. */
1878 stacktrace_stackframeinfo_remove(&sfi);
1882 #endif /* defined(ENABLE_JIT) */
1885 /* exceptions_print_exception **************************************************
1887 Prints an exception, the detail message and the cause, if
1888 available, with CACAO internal functions to stdout.
1890 *******************************************************************************/
1892 void exceptions_print_exception(java_handle_t *xptr)
1894 java_lang_Throwable jlt(xptr);
1896 if (jlt.is_null()) {
1901 #if defined(ENABLE_JAVASE)
1902 java_lang_Throwable jltcause(jlt.get_cause());
1905 /* print the root exception */
1907 classinfo* c = jlt.get_Class();
1908 utf_display_printable_ascii_classname(c->name);
1910 java_lang_String jls(jlt.get_detailMessage());
1912 if (!jls.is_null()) {
1913 utf* u = javastring_toutf(jls.get_handle(), false);
1916 utf_display_printable_ascii(u);
1921 #if defined(ENABLE_JAVASE)
1922 /* print the cause if available */
1924 // FIXME cause != t compare with operator override.
1925 if ((!jltcause.is_null()) && (jltcause.get_handle() != jlt.get_handle())) {
1926 printf("Caused by: ");
1928 c = jltcause.get_Class();
1929 utf_display_printable_ascii_classname(c->name);
1931 java_lang_String jlscause(jlt.get_detailMessage());
1933 if (jlscause.get_handle() != NULL) {
1934 utf* u = javastring_toutf(jlscause.get_handle(), false);
1937 utf_display_printable_ascii(u);
1946 /* exceptions_print_current_exception ******************************************
1948 Prints the current pending exception, the detail message and the
1949 cause, if available, with CACAO internal functions to stdout.
1951 *******************************************************************************/
1953 void exceptions_print_current_exception(void)
1957 o = exceptions_get_exception();
1959 exceptions_print_exception(o);
1963 /* exceptions_print_stacktrace *************************************************
1965 Prints a pending exception with Throwable.printStackTrace(). If
1966 there happens an exception during printStackTrace(), we print the
1967 thrown exception and the original one.
1969 NOTE: This function calls Java code.
1971 *******************************************************************************/
1973 void exceptions_print_stacktrace(void)
1980 #if defined(ENABLE_THREADS)
1982 java_lang_Thread *to;
1985 /* Get and clear exception because we are calling Java code
1988 e = exceptions_get_and_clear_exception();
1994 /* FIXME Enable me. */
1995 if (builtin_instanceof(e, class_java_lang_ThreadDeath)) {
1996 /* Don't print anything if we are being killed. */
2001 /* Get the exception class. */
2003 LLNI_class_get(e, c);
2005 /* Find the printStackTrace() method. */
2007 m = class_resolveclassmethod(c,
2008 utf_printStackTrace,
2010 class_java_lang_Object,
2014 VM::get_current()->abort("exceptions_print_stacktrace: printStackTrace()V not found");
2016 /* Print message. */
2018 fprintf(stderr, "Exception ");
2020 #if defined(ENABLE_THREADS)
2021 /* Print thread name. We get the thread here explicitly as we
2022 need it afterwards. */
2024 t = thread_get_current();
2025 to = (java_lang_Thread *) thread_get_object(t);
2028 fprintf(stderr, "in thread \"");
2029 thread_fprint_name(t, stderr);
2030 fprintf(stderr, "\" ");
2034 /* Print the stacktrace. */
2036 if (builtin_instanceof(e, class_java_lang_Throwable)) {
2037 (void) vm_call_method(m, e);
2039 /* If this happens we are EXTREMLY out of memory or have a
2040 serious problem while printStackTrace. But may be
2041 another exception, so print it. */
2043 ne = exceptions_get_exception();
2046 fprintf(stderr, "Exception while printStackTrace(): ");
2048 /* Print the current exception. */
2050 exceptions_print_exception(ne);
2051 stacktrace_print_exception(ne);
2053 /* Now print the original exception. */
2055 fprintf(stderr, "Original exception was: ");
2056 exceptions_print_exception(e);
2057 stacktrace_print_exception(e);
2061 fprintf(stderr, ". Uncaught exception of type ");
2062 #if !defined(NDEBUG)
2063 /* FIXME This prints to stdout. */
2066 fprintf(stderr, "UNKNOWN");
2068 fprintf(stderr, ".");
2079 * These are local overrides for various environment variables in Emacs.
2080 * Please do not remove this and leave it at the end of the file, where
2081 * Emacs will automagically detect them.
2082 * ---------------------------------------------------------------------
2085 * indent-tabs-mode: t
2089 * vim:noexpandtab:sw=4:ts=4: