* src/native/jni.c (_Jv_JNI_FindClass): Renamed to jni_FindClass, call
[cacao.git] / src / vm / exceptions.c
1 /* src/vm/exceptions.c - exception related functions
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
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.
12
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.
17
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
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <assert.h>
29 #include <string.h>
30 #include <stdarg.h>
31 #include <stdlib.h>
32 #include <sys/mman.h>
33
34 #include "vm/types.h"
35
36 #include "md-abi.h"
37
38 #include "mm/memory.h"
39
40 #include "native/jni.h"
41 #include "native/llni.h"
42 #include "native/native.h"
43
44 #include "native/include/java_lang_String.h"
45 #include "native/include/java_lang_Thread.h"
46 #include "native/include/java_lang_Throwable.h"
47
48 #include "threads/lock-common.h"
49 #include "threads/thread.h"
50
51 #include "toolbox/util.h"
52
53 #include "vm/builtin.h"
54 #include "vm/exceptions.h"
55 #include "vm/global.h"
56 #include "vm/stringlocal.h"
57 #include "vm/vm.h"
58
59 #include "vm/jit/asmpart.h"
60 #include "vm/jit/jit.h"
61 #include "vm/jit/methodheader.h"
62 #include "vm/jit/patcher-common.h"
63 #include "vm/jit/show.h"
64 #include "vm/jit/stacktrace.h"
65 #include "vm/jit/trace.h"
66
67 #include "vmcore/class.h"
68 #include "vmcore/loader.h"
69 #include "vmcore/method.h"
70 #include "vmcore/options.h"
71 #include "vmcore/system.h"
72
73 #if defined(ENABLE_VMLOG)
74 #include <vmlog_cacao.h>
75 #endif
76
77
78 /* for raising exceptions from native methods *********************************/
79
80 #if !defined(ENABLE_THREADS)
81 java_object_t *_no_threads_exceptionptr = NULL;
82 #endif
83
84
85 /* exceptions_init *************************************************************
86
87    Initialize the exceptions subsystem.
88
89 *******************************************************************************/
90
91 void exceptions_init(void)
92 {
93 #if !(defined(__ARM__) && defined(__LINUX__))
94         /* On arm-linux the first memory page can't be mmap'ed, as it
95            contains the exception vectors. */
96
97         int pagesize;
98
99         /* mmap a memory page at address 0x0, so our hardware-exceptions
100            work. */
101
102         pagesize = system_getpagesize();
103
104         (void) system_mmap_anonymous(NULL, pagesize, PROT_NONE, MAP_PRIVATE | MAP_FIXED);
105 #endif
106
107         TRACESUBSYSTEMINITIALIZATION("exceptions_init");
108
109         /* check if we get into trouble with our hardware-exceptions */
110
111         if (OFFSET(java_bytearray_t, data) <= EXCEPTION_HARDWARE_LARGEST)
112                 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 }
114
115
116 /* exceptions_get_exception ****************************************************
117
118    Returns the current exception pointer of the current thread.
119
120 *******************************************************************************/
121
122 java_handle_t *exceptions_get_exception(void)
123 {
124         java_object_t *o;
125         java_handle_t *e;
126 #if defined(ENABLE_THREADS)
127         threadobject  *t;
128
129         t = THREADOBJECT;
130 #endif
131
132         /* Get the exception. */
133
134         LLNI_CRITICAL_START;
135
136 #if defined(ENABLE_THREADS)
137         o = t->_exceptionptr;
138 #else
139         o = _no_threads_exceptionptr;
140 #endif
141
142         e = LLNI_WRAP(o);
143
144         LLNI_CRITICAL_END;
145
146         /* Return the exception. */
147
148         return e;
149 }
150
151
152 /* exceptions_set_exception ****************************************************
153
154    Sets the exception pointer of the current thread.
155
156 *******************************************************************************/
157
158 void exceptions_set_exception(java_handle_t *e)
159 {
160         threadobject  *t;
161         java_object_t *o;
162
163 #if defined(ENABLE_THREADS)
164         t = THREADOBJECT;
165 #else
166         t = NULL;
167 #endif
168
169         /* Set the exception. */
170
171         LLNI_CRITICAL_START;
172
173         o = LLNI_UNWRAP(e);
174
175 #if !defined(NDEBUG)
176         if (opt_DebugExceptions) {
177                 printf("[exceptions_set_exception  : t=%p, o=%p, class=",
178                            (void *) t, (void *) o);
179                 class_print(o->vftbl->class);
180                 printf("]\n");
181         }
182 #endif
183
184 #if defined(ENABLE_THREADS)
185         t->_exceptionptr = o;
186 #else
187         _no_threads_exceptionptr = o;
188 #endif
189
190         LLNI_CRITICAL_END;
191 }
192
193
194 /* exceptions_clear_exception **************************************************
195
196    Clears the current exception pointer of the current thread.
197
198 *******************************************************************************/
199
200 void exceptions_clear_exception(void)
201 {
202         threadobject *t;
203
204 #if defined(ENABLE_THREADS)
205         t = THREADOBJECT;
206 #else
207         t = NULL;
208 #endif
209
210         /* Set the exception. */
211
212 #if !defined(NDEBUG)
213         if (opt_DebugExceptions) {
214                 printf("[exceptions_clear_exception: t=%p]\n", (void *) t);
215         }
216 #endif
217
218 #if defined(ENABLE_THREADS)
219         t->_exceptionptr = NULL;
220 #else
221         _no_threads_exceptionptr = NULL;
222 #endif
223 }
224
225
226 /* exceptions_get_and_clear_exception ******************************************
227
228    Gets the exception pointer of the current thread and clears it.
229    This function may return NULL.
230
231 *******************************************************************************/
232
233 java_handle_t *exceptions_get_and_clear_exception(void)
234 {
235         java_handle_t *o;
236
237         /* Get the exception... */
238
239         o = exceptions_get_exception();
240
241         /* ...and clear the exception if it is set. */
242
243         if (o != NULL)
244                 exceptions_clear_exception();
245
246         /* return the exception */
247
248         return o;
249 }
250
251
252 /* exceptions_abort ************************************************************
253
254    Prints exception to be thrown and aborts.
255
256    IN:
257       classname....class name
258       message......exception message
259
260 *******************************************************************************/
261
262 static void exceptions_abort(utf *classname, utf *message)
263 {
264         log_println("exception thrown while VM is initializing: ");
265
266         log_start();
267         utf_display_printable_ascii_classname(classname);
268
269         if (message != NULL) {
270                 log_print(": ");
271                 utf_display_printable_ascii_classname(message);
272         }
273
274         log_finish();
275
276         vm_abort("Aborting...");
277 }
278
279
280 /* exceptions_new_class_utf ****************************************************
281
282    Creates an exception object with the given class and initalizes it
283    with the given utf message.
284
285    IN:
286       c ......... exception class
287           message ... the message as an utf *
288
289    RETURN VALUE:
290      an exception pointer (in any case -- either it is the newly
291      created exception, or an exception thrown while trying to create
292      it).
293
294 *******************************************************************************/
295
296 static java_handle_t *exceptions_new_class_utf(classinfo *c, utf *message)
297 {
298         java_handle_t *s;
299         java_handle_t *o;
300
301         if (vm_initializing)
302                 exceptions_abort(c->name, message);
303
304         s = javastring_new(message);
305
306         if (s == NULL)
307                 return exceptions_get_exception();
308
309         o = native_new_and_init_string(c, s);
310
311         if (o == NULL)
312                 return exceptions_get_exception();
313
314         return o;
315 }
316
317
318 /* exceptions_new_utf **********************************************************
319
320    Creates an exception object with the given name and initalizes it.
321
322    IN:
323       classname....class name in UTF-8
324
325 *******************************************************************************/
326
327 static java_handle_t *exceptions_new_utf(utf *classname)
328 {
329         classinfo     *c;
330         java_handle_t *o;
331
332         if (vm_initializing)
333                 exceptions_abort(classname, NULL);
334
335         c = load_class_bootstrap(classname);
336
337         if (c == NULL)
338                 return exceptions_get_exception();
339
340         o = native_new_and_init(c);
341
342         if (o == NULL)
343                 return exceptions_get_exception();
344
345         return o;
346 }
347
348
349 /* exceptions_new_utf_javastring ***********************************************
350
351    Creates an exception object with the given name and initalizes it
352    with the given java/lang/String message.
353
354    IN:
355       classname....class name in UTF-8
356           message......the message as a java.lang.String
357
358    RETURN VALUE:
359       an exception pointer (in any case -- either it is the newly created
360           exception, or an exception thrown while trying to create it).
361
362 *******************************************************************************/
363
364 static java_handle_t *exceptions_new_utf_javastring(utf *classname,
365                                                                                                         java_handle_t *message)
366 {
367         java_handle_t *o;
368         classinfo     *c;
369    
370         if (vm_initializing)
371                 exceptions_abort(classname, NULL);
372
373         c = load_class_bootstrap(classname);
374
375         if (c == NULL)
376                 return exceptions_get_exception();
377
378         o = native_new_and_init_string(c, message);
379
380         if (o == NULL)
381                 return exceptions_get_exception();
382
383         return o;
384 }
385
386
387 /* exceptions_new_utf_utf ******************************************************
388
389    Creates an exception object with the given name and initalizes it
390    with the given utf message.
391
392    IN:
393       classname....class name in UTF-8
394           message......the message as an utf *
395
396    RETURN VALUE:
397       an exception pointer (in any case -- either it is the newly created
398           exception, or an exception thrown while trying to create it).
399
400 *******************************************************************************/
401
402 static java_handle_t *exceptions_new_utf_utf(utf *classname, utf *message)
403 {
404         classinfo     *c;
405         java_handle_t *o;
406
407         if (vm_initializing)
408                 exceptions_abort(classname, message);
409
410         c = load_class_bootstrap(classname);
411
412         if (c == NULL)
413                 return exceptions_get_exception();
414
415         o = exceptions_new_class_utf(c, message);
416
417         return o;
418 }
419
420
421 /* exceptions_throw_class_utf **************************************************
422
423    Creates an exception object with the given class, initalizes and
424    throws it with the given utf message.
425
426    IN:
427       c ......... exception class
428           message ... the message as an utf *
429
430 *******************************************************************************/
431
432 static void exceptions_throw_class_utf(classinfo *c, utf *message)
433 {
434         java_handle_t *o;
435
436         o = exceptions_new_class_utf(c, message);
437
438         exceptions_set_exception(o);
439 }
440
441
442 /* exceptions_throw_utf ********************************************************
443
444    Creates an exception object with the given name, initalizes and
445    throws it.
446
447    IN:
448       classname....class name in UTF-8
449
450 *******************************************************************************/
451
452 static void exceptions_throw_utf(utf *classname)
453 {
454         java_handle_t *o;
455
456         o = exceptions_new_utf(classname);
457
458         if (o == NULL)
459                 return;
460
461         exceptions_set_exception(o);
462 }
463
464
465 /* exceptions_throw_utf_throwable **********************************************
466
467    Creates an exception object with the given name and initalizes it
468    with the given java/lang/Throwable exception.
469
470    IN:
471       classname....class name in UTF-8
472           cause........the given Throwable
473
474 *******************************************************************************/
475
476 static void exceptions_throw_utf_throwable(utf *classname,
477                                                                                    java_handle_t *cause)
478 {
479         classinfo           *c;
480         java_handle_t       *o;
481         methodinfo          *m;
482         java_lang_Throwable *object;
483
484         if (vm_initializing)
485                 exceptions_abort(classname, NULL);
486
487         object = (java_lang_Throwable *) cause;
488
489         c = load_class_bootstrap(classname);
490
491         if (c == NULL)
492                 return;
493
494         /* create object */
495
496         o = builtin_new(c);
497         
498         if (o == NULL)
499                 return;
500
501         /* call initializer */
502
503         m = class_resolveclassmethod(c,
504                                                                  utf_init,
505                                                                  utf_java_lang_Throwable__void,
506                                                                  NULL,
507                                                                  true);
508                                                       
509         if (m == NULL)
510                 return;
511
512         (void) vm_call_method(m, o, cause);
513
514         exceptions_set_exception(o);
515 }
516
517
518 /* exceptions_throw_utf_exception **********************************************
519
520    Creates an exception object with the given name and initalizes it
521    with the given java/lang/Exception exception.
522
523    IN:
524       classname....class name in UTF-8
525           exception....the given Exception
526
527 *******************************************************************************/
528
529 static void exceptions_throw_utf_exception(utf *classname,
530                                                                                    java_handle_t *exception)
531 {
532         classinfo     *c;
533         java_handle_t *o;
534         methodinfo    *m;
535
536         if (vm_initializing)
537                 exceptions_abort(classname, NULL);
538
539         c = load_class_bootstrap(classname);
540
541         if (c == NULL)
542                 return;
543
544         /* create object */
545
546         o = builtin_new(c);
547         
548         if (o == NULL)
549                 return;
550
551         /* call initializer */
552
553         m = class_resolveclassmethod(c,
554                                                                  utf_init,
555                                                                  utf_java_lang_Exception__V,
556                                                                  NULL,
557                                                                  true);
558                                                       
559         if (m == NULL)
560                 return;
561
562         (void) vm_call_method(m, o, exception);
563
564         exceptions_set_exception(o);
565 }
566
567
568 /* exceptions_throw_utf_cause **************************************************
569
570    Creates an exception object with the given name and initalizes it
571    with the given java/lang/Throwable exception with initCause.
572
573    IN:
574       classname....class name in UTF-8
575           cause........the given Throwable
576
577 *******************************************************************************/
578
579 static void exceptions_throw_utf_cause(utf *classname, java_handle_t *cause)
580 {
581         classinfo           *c;
582         java_handle_t       *o;
583         methodinfo          *m;
584         java_lang_String    *s;
585         java_lang_Throwable *object;
586
587         if (vm_initializing)
588                 exceptions_abort(classname, NULL);
589
590         object = (java_lang_Throwable *) cause;
591
592         c = load_class_bootstrap(classname);
593
594         if (c == NULL)
595                 return;
596
597         /* create object */
598
599         o = builtin_new(c);
600         
601         if (o == NULL)
602                 return;
603
604         /* call initializer */
605
606         m = class_resolveclassmethod(c,
607                                                                  utf_init,
608                                                                  utf_java_lang_String__void,
609                                                                  NULL,
610                                                                  true);
611                                                       
612         if (m == NULL)
613                 return;
614
615         LLNI_field_get_ref(object, detailMessage, s);
616
617         (void) vm_call_method(m, o, s);
618
619         /* call initCause */
620
621         m = class_resolveclassmethod(c,
622                                                                  utf_initCause,
623                                                                  utf_java_lang_Throwable__java_lang_Throwable,
624                                                                  NULL,
625                                                                  true);
626
627         if (m == NULL)
628                 return;
629
630         (void) vm_call_method(m, o, cause);
631
632         exceptions_set_exception(o);
633 }
634
635
636 /* exceptions_throw_utf_utf ****************************************************
637
638    Creates an exception object with the given name, initalizes and
639    throws it with the given utf message.
640
641    IN:
642       classname....class name in UTF-8
643           message......the message as an utf *
644
645 *******************************************************************************/
646
647 static void exceptions_throw_utf_utf(utf *classname, utf *message)
648 {
649         java_handle_t *o;
650
651         o = exceptions_new_utf_utf(classname, message);
652
653         exceptions_set_exception(o);
654 }
655
656
657 /* exceptions_new_abstractmethoderror ****************************************
658
659    Generates a java.lang.AbstractMethodError for the VM.
660
661 *******************************************************************************/
662
663 java_handle_t *exceptions_new_abstractmethoderror(void)
664 {
665         java_handle_t *o;
666
667         o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
668
669         return o;
670 }
671
672
673 /* exceptions_new_error ********************************************************
674
675    Generates a java.lang.Error for the VM.
676
677 *******************************************************************************/
678
679 #if defined(ENABLE_JAVAME_CLDC1_1)
680 static java_handle_t *exceptions_new_error(utf *message)
681 {
682         java_handle_t *o;
683
684         o = exceptions_new_utf_utf(utf_java_lang_Error, message);
685
686         return o;
687 }
688 #endif
689
690
691 /* exceptions_asm_new_abstractmethoderror **************************************
692
693    Generates a java.lang.AbstractMethodError for
694    asm_abstractmethoderror.
695
696 *******************************************************************************/
697
698 java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
699 {
700         stackframeinfo_t  sfi;
701         java_handle_t    *e;
702         java_object_t    *o;
703
704         /* Fill and add a stackframeinfo (XPC is equal to RA). */
705
706         stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra);
707
708         /* create the exception */
709
710 #if defined(ENABLE_JAVASE)
711         e = exceptions_new_abstractmethoderror();
712 #else
713         e = exceptions_new_error(utf_java_lang_AbstractMethodError);
714 #endif
715
716         /* Remove the stackframeinfo. */
717
718         stacktrace_stackframeinfo_remove(&sfi);
719
720         /* unwrap the exception */
721         /* ATTENTION: do the this _after_ the stackframeinfo was removed */
722
723         o = LLNI_UNWRAP(e);
724
725         return o;
726 }
727
728
729 /* exceptions_new_arraystoreexception ******************************************
730
731    Generates a java.lang.ArrayStoreException for the VM.
732
733 *******************************************************************************/
734
735 java_handle_t *exceptions_new_arraystoreexception(void)
736 {
737         java_handle_t *o;
738
739         o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
740
741         return o;
742 }
743
744
745 /* exceptions_throw_abstractmethoderror ****************************************
746
747    Generates and throws a java.lang.AbstractMethodError for the VM.
748
749 *******************************************************************************/
750
751 void exceptions_throw_abstractmethoderror(void)
752 {
753         exceptions_throw_utf(utf_java_lang_AbstractMethodError);
754 }
755
756
757 /* exceptions_throw_classcircularityerror **************************************
758
759    Generates and throws a java.lang.ClassCircularityError for the
760    classloader.
761
762    IN:
763       c....the class in which the error was found
764
765 *******************************************************************************/
766
767 void exceptions_throw_classcircularityerror(classinfo *c)
768 {
769         exceptions_throw_utf_utf(utf_java_lang_ClassCircularityError, c->name);
770 }
771
772
773 /* exceptions_throw_classformaterror *******************************************
774
775    Generates and throws a java.lang.ClassFormatError for the VM.
776
777    IN:
778       c............the class in which the error was found
779           message......UTF-8 format string
780
781 *******************************************************************************/
782
783 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
784 {
785         char    *msg;
786         s4       msglen;
787         va_list  ap;
788         utf     *u;
789
790         /* calculate message length */
791
792         msglen = 0;
793
794         if (c != NULL)
795                 msglen += utf_bytes(c->name) + strlen(" (");
796
797         va_start(ap, message);
798         msglen += get_variable_message_length(message, ap);
799         va_end(ap);
800
801         if (c != NULL)
802                 msglen += strlen(")");
803
804         msglen += strlen("0");
805
806         /* allocate a buffer */
807
808         msg = MNEW(char, msglen);
809
810         /* print message into allocated buffer */
811
812         if (c != NULL) {
813                 utf_copy_classname(msg, c->name);
814                 strcat(msg, " (");
815         }
816
817         va_start(ap, message);
818         vsprintf(msg + strlen(msg), message, ap);
819         va_end(ap);
820
821         if (c != NULL)
822                 strcat(msg, ")");
823
824         u = utf_new_char(msg);
825
826         /* free memory */
827
828         MFREE(msg, char, msglen);
829
830         /* throw exception */
831
832         exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
833 }
834
835
836 /* exceptions_throw_classnotfoundexception *************************************
837
838    Generates and throws a java.lang.ClassNotFoundException for the
839    VM.
840
841    IN:
842       name.........name of the class not found as a utf *
843
844 *******************************************************************************/
845
846 void exceptions_throw_classnotfoundexception(utf *name)
847 {       
848         exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
849 }
850
851
852 /* exceptions_throw_noclassdeffounderror ***************************************
853
854    Generates and throws a java.lang.NoClassDefFoundError.
855
856    IN:
857       name.........name of the class not found as a utf *
858
859 *******************************************************************************/
860
861 void exceptions_throw_noclassdeffounderror(utf *name)
862 {
863         exceptions_throw_utf_utf(utf_java_lang_NoClassDefFoundError, name);
864 }
865
866
867 /* exceptions_throw_noclassdeffounderror_cause *********************************
868
869    Generates and throws a java.lang.NoClassDefFoundError with the
870    given cause.
871
872 *******************************************************************************/
873
874 void exceptions_throw_noclassdeffounderror_cause(java_handle_t *cause)
875 {
876         exceptions_throw_utf_cause(utf_java_lang_NoClassDefFoundError, cause);
877 }
878
879
880 /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
881
882    Generates and throws a java.lang.NoClassDefFoundError with a
883    specific message:
884
885    IN:
886       name.........name of the class not found as a utf *
887
888 *******************************************************************************/
889
890 void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
891 {
892         char *msg;
893         s4    msglen;
894         utf  *u;
895
896         msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
897                 utf_bytes(name) + strlen(")") + strlen("0");
898
899         msg = MNEW(char, msglen);
900
901         utf_copy_classname(msg, c->name);
902         strcat(msg, " (wrong name: ");
903         utf_cat_classname(msg, name);
904         strcat(msg, ")");
905
906         u = utf_new_char(msg);
907
908         MFREE(msg, char, msglen);
909
910         exceptions_throw_noclassdeffounderror(u);
911 }
912
913
914 /* exceptions_throw_exceptionininitializererror ********************************
915
916    Generates and throws a java.lang.ExceptionInInitializerError for
917    the VM.
918
919    IN:
920       cause......cause exception object
921
922 *******************************************************************************/
923
924 void exceptions_throw_exceptionininitializererror(java_handle_t *cause)
925 {
926         exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
927                                                                    cause);
928 }
929
930
931 /* exceptions_throw_incompatibleclasschangeerror *******************************
932
933    Generates and throws a java.lang.IncompatibleClassChangeError for
934    the VM.
935
936    IN:
937       message......UTF-8 message format string
938
939 *******************************************************************************/
940
941 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
942 {
943         char *msg;
944         s4    msglen;
945         utf  *u;
946
947         /* calculate exception message length */
948
949         msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
950
951         /* allocate memory */
952
953         msg = MNEW(char, msglen);
954
955         utf_copy_classname(msg, c->name);
956         strcat(msg, message);
957
958         u = utf_new_char(msg);
959
960         /* free memory */
961
962         MFREE(msg, char, msglen);
963
964         /* throw exception */
965
966         exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
967 }
968
969
970 /* exceptions_throw_instantiationerror *****************************************
971
972    Generates and throws a java.lang.InstantiationError for the VM.
973
974 *******************************************************************************/
975
976 void exceptions_throw_instantiationerror(classinfo *c)
977 {
978         exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
979 }
980
981
982 /* exceptions_throw_internalerror **********************************************
983
984    Generates and throws a java.lang.InternalError for the VM.
985
986    IN:
987       message......UTF-8 message format string
988
989 *******************************************************************************/
990
991 void exceptions_throw_internalerror(const char *message, ...)
992 {
993         va_list  ap;
994         char    *msg;
995         s4       msglen;
996         utf     *u;
997
998         /* calculate exception message length */
999
1000         va_start(ap, message);
1001         msglen = get_variable_message_length(message, ap);
1002         va_end(ap);
1003
1004         /* allocate memory */
1005
1006         msg = MNEW(char, msglen);
1007
1008         /* generate message */
1009
1010         va_start(ap, message);
1011         vsprintf(msg, message, ap);
1012         va_end(ap);
1013
1014         u = utf_new_char(msg);
1015
1016         /* free memory */
1017
1018         MFREE(msg, char, msglen);
1019
1020         /* throw exception */
1021
1022         exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
1023 }
1024
1025
1026 /* exceptions_throw_linkageerror ***********************************************
1027
1028    Generates and throws java.lang.LinkageError with an error message.
1029
1030    IN:
1031       message......UTF-8 message
1032           c............class related to the error. If this is != NULL
1033                        the name of c is appended to the error message.
1034
1035 *******************************************************************************/
1036
1037 void exceptions_throw_linkageerror(const char *message, classinfo *c)
1038 {
1039         utf  *u;
1040         char *msg;
1041         int   len;
1042
1043         /* calculate exception message length */
1044
1045         len = strlen(message) + 1;
1046
1047         if (c != NULL)
1048                 len += utf_bytes(c->name);
1049                 
1050         /* allocate memory */
1051
1052         msg = MNEW(char, len);
1053
1054         /* generate message */
1055
1056         strcpy(msg, message);
1057
1058         if (c != NULL)
1059                 utf_cat_classname(msg, c->name);
1060
1061         u = utf_new_char(msg);
1062
1063         /* free memory */
1064
1065         MFREE(msg, char, len);
1066
1067         exceptions_throw_utf_utf(utf_java_lang_LinkageError, u);
1068 }
1069
1070
1071 /* exceptions_throw_nosuchfielderror *******************************************
1072
1073    Generates and throws a java.lang.NoSuchFieldError with an error
1074    message.
1075
1076    IN:
1077       c............class in which the field was not found
1078           name.........name of the field
1079
1080 *******************************************************************************/
1081
1082 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
1083 {
1084         char *msg;
1085         s4    msglen;
1086         utf  *u;
1087
1088         /* calculate exception message length */
1089
1090         msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
1091
1092         /* allocate memory */
1093
1094         msg = MNEW(char, msglen);
1095
1096         /* generate message */
1097
1098         utf_copy_classname(msg, c->name);
1099         strcat(msg, ".");
1100         utf_cat(msg, name);
1101
1102         u = utf_new_char(msg);
1103
1104         /* free memory */
1105
1106         MFREE(msg, char, msglen);
1107
1108         exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
1109 }
1110
1111
1112 /* exceptions_throw_nosuchmethoderror ******************************************
1113
1114    Generates and throws a java.lang.NoSuchMethodError with an error
1115    message.
1116
1117    IN:
1118       c............class in which the method was not found
1119           name.........name of the method
1120           desc.........descriptor of the method
1121
1122 *******************************************************************************/
1123
1124 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
1125 {
1126         char *msg;
1127         s4    msglen;
1128         utf  *u;
1129
1130         /* calculate exception message length */
1131
1132         msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
1133                 utf_bytes(desc) + strlen("0");
1134
1135         /* allocate memory */
1136
1137         msg = MNEW(char, msglen);
1138
1139         /* generate message */
1140
1141         utf_copy_classname(msg, c->name);
1142         strcat(msg, ".");
1143         utf_cat(msg, name);
1144         utf_cat(msg, desc);
1145
1146         u = utf_new_char(msg);
1147
1148         /* free memory */
1149
1150         MFREE(msg, char, msglen);
1151
1152 #if defined(ENABLE_JAVASE)
1153         exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
1154 #else
1155         exceptions_throw_utf_utf(utf_java_lang_Error, u);
1156 #endif
1157 }
1158
1159
1160 /* exceptions_throw_outofmemoryerror *******************************************
1161
1162    Generates and throws an java.lang.OutOfMemoryError for the VM.
1163
1164 *******************************************************************************/
1165
1166 void exceptions_throw_outofmemoryerror(void)
1167 {
1168         exceptions_throw_utf(utf_java_lang_OutOfMemoryError);
1169 }
1170
1171
1172 /* exceptions_throw_unsatisfiedlinkerror ***************************************
1173
1174    Generates and throws a java.lang.UnsatisfiedLinkError for the
1175    classloader.
1176
1177    IN:
1178           name......UTF-8 name string
1179
1180 *******************************************************************************/
1181
1182 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1183 {
1184 #if defined(ENABLE_JAVASE)
1185         exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1186 #else
1187         exceptions_throw_utf_utf(utf_java_lang_Error, name);
1188 #endif
1189 }
1190
1191
1192 /* exceptions_throw_unsupportedclassversionerror *******************************
1193
1194    Generates and throws a java.lang.UnsupportedClassVersionError for
1195    the classloader.
1196
1197    IN:
1198       c............class in which the method was not found
1199           message......UTF-8 format string
1200
1201 *******************************************************************************/
1202
1203 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1204 {
1205         char *msg;
1206     s4    msglen;
1207         utf  *u;
1208
1209         /* calculate exception message length */
1210
1211         msglen =
1212                 utf_bytes(c->name) +
1213                 strlen(" (Unsupported major.minor version 00.0)") +
1214                 strlen("0");
1215
1216         /* allocate memory */
1217
1218         msg = MNEW(char, msglen);
1219
1220         /* generate message */
1221
1222         utf_copy_classname(msg, c->name);
1223         sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1224                         ma, mi);
1225
1226         u = utf_new_char(msg);
1227
1228         /* free memory */
1229
1230         MFREE(msg, char, msglen);
1231
1232         /* throw exception */
1233
1234         exceptions_throw_utf_utf(utf_java_lang_UnsupportedClassVersionError, u);
1235 }
1236
1237
1238 /* exceptions_throw_verifyerror ************************************************
1239
1240    Generates and throws a java.lang.VerifyError for the JIT compiler.
1241
1242    IN:
1243       m............method in which the error was found
1244           message......UTF-8 format string
1245
1246 *******************************************************************************/
1247
1248 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1249 {
1250         va_list  ap;
1251         char    *msg;
1252         s4       msglen;
1253         utf     *u;
1254
1255         /* calculate exception message length */
1256
1257         msglen = 0;
1258
1259         if (m != NULL)
1260                 msglen =
1261                         strlen("(class: ") + utf_bytes(m->class->name) +
1262                         strlen(", method: ") + utf_bytes(m->name) +
1263                         strlen(" signature: ") + utf_bytes(m->descriptor) +
1264                         strlen(") ") + strlen("0");
1265
1266         va_start(ap, message);
1267         msglen += get_variable_message_length(message, ap);
1268         va_end(ap);
1269
1270         /* allocate memory */
1271
1272         msg = MNEW(char, msglen);
1273
1274         /* generate message */
1275
1276         if (m != NULL) {
1277                 strcpy(msg, "(class: ");
1278                 utf_cat_classname(msg, m->class->name);
1279                 strcat(msg, ", method: ");
1280                 utf_cat(msg, m->name);
1281                 strcat(msg, " signature: ");
1282                 utf_cat(msg, m->descriptor);
1283                 strcat(msg, ") ");
1284         }
1285
1286         va_start(ap, message);
1287         vsprintf(msg + strlen(msg), message, ap);
1288         va_end(ap);
1289
1290         u = utf_new_char(msg);
1291
1292         /* free memory */
1293
1294         MFREE(msg, char, msglen);
1295
1296         /* throw exception */
1297
1298         exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1299 }
1300
1301
1302 /* exceptions_throw_verifyerror_for_stack **************************************
1303
1304    throws a java.lang.VerifyError for an invalid stack slot type
1305
1306    IN:
1307       m............method in which the error was found
1308           type.........the expected type
1309
1310    RETURN VALUE:
1311       an exception pointer (in any case -- either it is the newly created
1312           exception, or an exception thrown while trying to create it).
1313
1314 *******************************************************************************/
1315
1316 void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
1317 {
1318         char *msg;
1319         s4    msglen;
1320         char *typename;
1321         utf  *u;
1322
1323         /* calculate exception message length */
1324
1325         msglen = 0;
1326
1327         if (m != NULL)
1328                 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1329                         strlen(", method: ") + utf_bytes(m->name) +
1330                         strlen(" signature: ") + utf_bytes(m->descriptor) +
1331                         strlen(") Expecting to find longest-------typename on stack") 
1332                         + strlen("0");
1333
1334         /* allocate memory */
1335
1336         msg = MNEW(char, msglen);
1337
1338         /* generate message */
1339
1340         if (m != NULL) {
1341                 strcpy(msg, "(class: ");
1342                 utf_cat_classname(msg, m->class->name);
1343                 strcat(msg, ", method: ");
1344                 utf_cat(msg, m->name);
1345                 strcat(msg, " signature: ");
1346                 utf_cat(msg, m->descriptor);
1347                 strcat(msg, ") ");
1348         }
1349         else {
1350                 msg[0] = 0;
1351         }
1352
1353         strcat(msg, "Expecting to find ");
1354
1355         switch (type) {
1356                 case TYPE_INT: typename = "integer"; break;
1357                 case TYPE_LNG: typename = "long"; break;
1358                 case TYPE_FLT: typename = "float"; break;
1359                 case TYPE_DBL: typename = "double"; break;
1360                 case TYPE_ADR: typename = "object/array"; break;
1361                 case TYPE_RET: typename = "returnAddress"; break;
1362                 default:       typename = "<INVALID>"; assert(0); break;
1363         }
1364
1365         strcat(msg, typename);
1366         strcat(msg, " on stack");
1367
1368         u = utf_new_char(msg);
1369
1370         /* free memory */
1371
1372         MFREE(msg, char, msglen);
1373
1374         /* throw exception */
1375
1376         exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1377 }
1378
1379
1380 /* exceptions_new_arithmeticexception ******************************************
1381
1382    Generates a java.lang.ArithmeticException for the JIT compiler.
1383
1384 *******************************************************************************/
1385
1386 java_handle_t *exceptions_new_arithmeticexception(void)
1387 {
1388         java_handle_t *o;
1389
1390         o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
1391                                                            utf_division_by_zero);
1392
1393         return o;
1394 }
1395
1396
1397 /* exceptions_new_arrayindexoutofboundsexception *******************************
1398
1399    Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1400    system.
1401
1402 *******************************************************************************/
1403
1404 java_handle_t *exceptions_new_arrayindexoutofboundsexception(s4 index)
1405 {
1406         java_handle_t *o;
1407         methodinfo    *m;
1408         java_handle_t *s;
1409
1410         /* convert the index into a String, like Sun does */
1411
1412         m = class_resolveclassmethod(class_java_lang_String,
1413                                                                  utf_new_char("valueOf"),
1414                                                                  utf_new_char("(I)Ljava/lang/String;"),
1415                                                                  class_java_lang_Object,
1416                                                                  true);
1417
1418         if (m == NULL)
1419                 return exceptions_get_exception();
1420
1421         s = vm_call_method(m, NULL, index);
1422
1423         if (s == NULL)
1424                 return exceptions_get_exception();
1425
1426         o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1427                                                                           s);
1428
1429         if (o == NULL)
1430                 return exceptions_get_exception();
1431
1432         return o;
1433 }
1434
1435
1436 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1437
1438    Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1439    the VM.
1440
1441 *******************************************************************************/
1442
1443 void exceptions_throw_arrayindexoutofboundsexception(void)
1444 {
1445         exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1446 }
1447
1448
1449 /* exceptions_throw_arraystoreexception ****************************************
1450
1451    Generates and throws a java.lang.ArrayStoreException for the VM.
1452
1453 *******************************************************************************/
1454
1455 void exceptions_throw_arraystoreexception(void)
1456 {
1457         exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1458 }
1459
1460
1461 /* exceptions_new_classcastexception *******************************************
1462
1463    Generates a java.lang.ClassCastException for the JIT compiler.
1464
1465 *******************************************************************************/
1466
1467 java_handle_t *exceptions_new_classcastexception(java_handle_t *o)
1468 {
1469         java_handle_t *e;
1470         classinfo     *c;
1471         utf           *classname;
1472
1473         LLNI_class_get(o, c);
1474
1475         classname = c->name;
1476
1477         e = exceptions_new_utf_utf(utf_java_lang_ClassCastException, classname);
1478
1479         return e;
1480 }
1481
1482
1483 /* exceptions_throw_clonenotsupportedexception *********************************
1484
1485    Generates and throws a java.lang.CloneNotSupportedException for the
1486    VM.
1487
1488 *******************************************************************************/
1489
1490 void exceptions_throw_clonenotsupportedexception(void)
1491 {
1492         exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1493 }
1494
1495
1496 /* exceptions_throw_illegalaccessexception *************************************
1497
1498    Generates and throws a java.lang.IllegalAccessException for the VM.
1499
1500 *******************************************************************************/
1501
1502 void exceptions_throw_illegalaccessexception(utf *message)
1503 {
1504         exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
1505 }
1506
1507
1508 /* exceptions_throw_illegalargumentexception ***********************************
1509
1510    Generates and throws a java.lang.IllegalArgumentException for the
1511    VM.
1512
1513 *******************************************************************************/
1514
1515 void exceptions_throw_illegalargumentexception(void)
1516 {
1517         exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1518 }
1519
1520
1521 /* exceptions_throw_illegalmonitorstateexception *******************************
1522
1523    Generates and throws a java.lang.IllegalMonitorStateException for
1524    the VM.
1525
1526 *******************************************************************************/
1527
1528 void exceptions_throw_illegalmonitorstateexception(void)
1529 {
1530         exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1531 }
1532
1533
1534 /* exceptions_throw_instantiationexception *************************************
1535
1536    Generates and throws a java.lang.InstantiationException for the VM.
1537
1538 *******************************************************************************/
1539
1540 void exceptions_throw_instantiationexception(classinfo *c)
1541 {
1542         exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1543 }
1544
1545
1546 /* exceptions_throw_interruptedexception ***************************************
1547
1548    Generates and throws a java.lang.InterruptedException for the VM.
1549
1550 *******************************************************************************/
1551
1552 void exceptions_throw_interruptedexception(void)
1553 {
1554         exceptions_throw_utf(utf_java_lang_InterruptedException);
1555 }
1556
1557
1558 /* exceptions_throw_invocationtargetexception **********************************
1559
1560    Generates and throws a java.lang.reflect.InvocationTargetException
1561    for the VM.
1562
1563    IN:
1564       cause......cause exception object
1565
1566 *******************************************************************************/
1567
1568 void exceptions_throw_invocationtargetexception(java_handle_t *cause)
1569 {
1570         exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1571                                                                    cause);
1572 }
1573
1574
1575 /* exceptions_throw_negativearraysizeexception *********************************
1576
1577    Generates and throws a java.lang.NegativeArraySizeException for the
1578    VM.
1579
1580 *******************************************************************************/
1581
1582 void exceptions_throw_negativearraysizeexception(void)
1583 {
1584         exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1585 }
1586
1587
1588 /* exceptions_new_nullpointerexception *****************************************
1589
1590    Generates a java.lang.NullPointerException for the VM system.
1591
1592 *******************************************************************************/
1593
1594 java_handle_t *exceptions_new_nullpointerexception(void)
1595 {
1596         java_handle_t *o;
1597
1598         o = exceptions_new_utf(utf_java_lang_NullPointerException);
1599
1600         return o;
1601 }
1602
1603
1604 /* exceptions_throw_nullpointerexception ***************************************
1605
1606    Generates a java.lang.NullPointerException for the VM system and
1607    throw it in the VM system.
1608
1609 *******************************************************************************/
1610
1611 void exceptions_throw_nullpointerexception(void)
1612 {
1613         exceptions_throw_utf(utf_java_lang_NullPointerException);
1614 }
1615
1616
1617 /* exceptions_throw_privilegedactionexception **********************************
1618
1619    Generates and throws a java.security.PrivilegedActionException.
1620
1621 *******************************************************************************/
1622
1623 void exceptions_throw_privilegedactionexception(java_handle_t *exception)
1624 {
1625         exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
1626                                                                    exception);
1627 }
1628
1629
1630 /* exceptions_throw_stringindexoutofboundsexception ****************************
1631
1632    Generates and throws a java.lang.StringIndexOutOfBoundsException
1633    for the VM.
1634
1635 *******************************************************************************/
1636
1637 void exceptions_throw_stringindexoutofboundsexception(void)
1638 {
1639         exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1640 }
1641
1642
1643 /* exceptions_fillinstacktrace *************************************************
1644
1645    Calls the fillInStackTrace-method of the currently thrown
1646    exception.
1647
1648 *******************************************************************************/
1649
1650 java_handle_t *exceptions_fillinstacktrace(void)
1651 {
1652         java_handle_t *o;
1653         classinfo     *c;
1654         methodinfo    *m;
1655
1656         /* get exception */
1657
1658         o = exceptions_get_and_clear_exception();
1659
1660         assert(o);
1661
1662         /* resolve methodinfo pointer from exception object */
1663
1664         LLNI_class_get(o, c);
1665
1666 #if defined(ENABLE_JAVASE)
1667         m = class_resolvemethod(c,
1668                                                         utf_fillInStackTrace,
1669                                                         utf_void__java_lang_Throwable);
1670 #elif defined(ENABLE_JAVAME_CLDC1_1)
1671         m = class_resolvemethod(c,
1672                                                         utf_fillInStackTrace,
1673                                                         utf_void__void);
1674 #else
1675 #error IMPLEMENT ME!
1676 #endif
1677
1678         /* call function */
1679
1680         (void) vm_call_method(m, o);
1681
1682         /* return exception object */
1683
1684         return o;
1685 }
1686
1687
1688 /* exceptions_handle_exception *************************************************
1689
1690    Try to find an exception handler for the given exception and return it.
1691    If no handler is found, exit the monitor of the method (if any)
1692    and return NULL.
1693
1694    IN:
1695       xptr.........the exception object
1696           xpc..........PC of where the exception was thrown
1697           pv...........Procedure Value of the current method
1698           sp...........current stack pointer
1699
1700    RETURN VALUE:
1701       the address of the first matching exception handler, or
1702           NULL if no handler was found
1703
1704 *******************************************************************************/
1705
1706 #if defined(ENABLE_JIT)
1707 void *exceptions_handle_exception(java_object_t *xptro, void *xpc, void *pv, void *sp)
1708 {
1709         stackframeinfo_t        sfi;
1710         java_handle_t          *xptr;
1711         methodinfo             *m;
1712         codeinfo               *code;
1713         exceptiontable_t       *et;
1714         exceptiontable_entry_t *ete;
1715         s4                      i;
1716         classref_or_classinfo   cr;
1717         classinfo              *c;
1718 #if defined(ENABLE_THREADS)
1719         java_object_t          *o;
1720 #endif
1721         void                   *result;
1722
1723 #ifdef __S390__
1724         /* Addresses are 31 bit integers */
1725 #       define ADDR_MASK(x) (void *) ((uintptr_t) (x) & 0x7FFFFFFF)
1726 #else
1727 #       define ADDR_MASK(x) (x)
1728 #endif
1729
1730         xptr = LLNI_WRAP(xptro);
1731         xpc  = ADDR_MASK(xpc);
1732
1733         /* Fill and add a stackframeinfo (XPC is equal to RA). */
1734
1735         stacktrace_stackframeinfo_add(&sfi, pv, sp, xpc, xpc);
1736
1737         result = NULL;
1738
1739         /* Get the codeinfo for the current method. */
1740
1741         code = code_get_codeinfo_for_pv(pv);
1742
1743         /* Get the methodinfo pointer from the codeinfo pointer. For
1744            asm_vm_call_method the codeinfo pointer is NULL and we simply
1745            can return the proper exception handler. */
1746
1747         if (code == NULL) {
1748                 result = (void *) (uintptr_t) &asm_vm_call_method_exception_handler;
1749                 goto exceptions_handle_exception_return;
1750         }
1751
1752         m = code->m;
1753
1754 #if !defined(NDEBUG)
1755         /* print exception trace */
1756
1757         if (opt_TraceExceptions)
1758                 trace_exception(LLNI_DIRECT(xptr), m, xpc);
1759
1760 # if defined(ENABLE_VMLOG)
1761         vmlog_cacao_throw(xptr);
1762 # endif
1763 #endif
1764
1765         /* Get the exception table. */
1766
1767         et = code->exceptiontable;
1768
1769         if (et != NULL) {
1770         /* Iterate over all exception table entries. */
1771
1772         ete = et->entries;
1773
1774         for (i = 0; i < et->length; i++, ete++) {
1775                 /* is the xpc is the current catch range */
1776
1777                 if ((ADDR_MASK(ete->startpc) <= xpc) && (xpc < ADDR_MASK(ete->endpc))) {
1778                         cr = ete->catchtype;
1779
1780                         /* NULL catches everything */
1781
1782                         if (cr.any == NULL) {
1783 #if !defined(NDEBUG)
1784                                 /* Print stacktrace of exception when caught. */
1785
1786 # if defined(ENABLE_VMLOG)
1787                                 vmlog_cacao_catch(xptr);
1788 # endif
1789
1790                                 if (opt_TraceExceptions) {
1791                                         exceptions_print_exception(xptr);
1792                                         stacktrace_print_exception(xptr);
1793                                 }
1794 #endif
1795
1796                                 result = ete->handlerpc;
1797                                 goto exceptions_handle_exception_return;
1798                         }
1799
1800                         /* resolve or load/link the exception class */
1801
1802                         if (IS_CLASSREF(cr)) {
1803                                 /* The exception class reference is unresolved. */
1804                                 /* We have to do _eager_ resolving here. While the
1805                                    class of the exception object is guaranteed to be
1806                                    loaded, it may well have been loaded by a different
1807                                    loader than the defining loader of m's class, which
1808                                    is the one we must use to resolve the catch
1809                                    class. Thus lazy resolving might fail, even if the
1810                                    result of the resolution would be an already loaded
1811                                    class. */
1812
1813                                 c = resolve_classref_eager(cr.ref);
1814
1815                                 if (c == NULL) {
1816                                         /* Exception resolving the exception class, argh! */
1817                                         goto exceptions_handle_exception_return;
1818                                 }
1819
1820                                 /* Ok, we resolved it. Enter it in the table, so we
1821                                    don't have to do this again. */
1822                                 /* XXX this write should be atomic. Is it? */
1823
1824                                 ete->catchtype.cls = c;
1825                         }
1826                         else {
1827                                 c = cr.cls;
1828
1829                                 /* XXX I don't think this case can ever happen. -Edwin */
1830                                 if (!(c->state & CLASS_LOADED))
1831                                         /* use the methods' classloader */
1832                                         if (!load_class_from_classloader(c->name,
1833                                                                                                          m->class->classloader))
1834                                                 goto exceptions_handle_exception_return;
1835
1836                                 /* XXX I think, if it is not linked, we can be sure
1837                                    that the exception object is no (indirect) instance
1838                                    of it, no?  -Edwin  */
1839                                 if (!(c->state & CLASS_LINKED))
1840                                         if (!link_class(c))
1841                                                 goto exceptions_handle_exception_return;
1842                         }
1843
1844                         /* is the thrown exception an instance of the catch class? */
1845
1846                         if (builtin_instanceof(xptr, c)) {
1847 #if !defined(NDEBUG)
1848                                 /* Print stacktrace of exception when caught. */
1849
1850 # if defined(ENABLE_VMLOG)
1851                                 vmlog_cacao_catch(xptr);
1852 # endif
1853
1854                                 if (opt_TraceExceptions) {
1855                                         exceptions_print_exception(xptr);
1856                                         stacktrace_print_exception(xptr);
1857                                 }
1858 #endif
1859
1860                                 result = ete->handlerpc;
1861                                 goto exceptions_handle_exception_return;
1862                         }
1863                 }
1864         }
1865         }
1866
1867 #if defined(ENABLE_THREADS)
1868         /* Is this method realization synchronized? */
1869
1870         if (code_is_synchronized(code)) {
1871                 /* Get synchronization object. */
1872
1873                 o = *((java_object_t **) (((uintptr_t) sp) + code->synchronizedoffset));
1874
1875                 assert(o != NULL);
1876
1877                 lock_monitor_exit(LLNI_QUICKWRAP(o));
1878         }
1879 #endif
1880
1881         /* none of the exceptions catch this one */
1882
1883 #if !defined(NDEBUG)
1884 # if defined(ENABLE_VMLOG)
1885         vmlog_cacao_unwnd_method(m);
1886 # endif
1887
1888 # if defined(ENABLE_DEBUG_FILTER)
1889         if (show_filters_test_verbosecall_exit(m)) {
1890 # endif
1891
1892         /* outdent the log message */
1893
1894         if (opt_verbosecall) {
1895                 if (TRACEJAVACALLINDENT)
1896                         TRACEJAVACALLINDENT--;
1897                 else
1898                         log_text("exceptions_handle_exception: WARNING: unmatched unindent");
1899         }
1900
1901 # if defined(ENABLE_DEBUG_FILTER)
1902         }
1903 # endif
1904 #endif /* !defined(NDEBUG) */
1905
1906         result = NULL;
1907
1908 exceptions_handle_exception_return:
1909
1910         /* Remove the stackframeinfo. */
1911
1912         stacktrace_stackframeinfo_remove(&sfi);
1913
1914         return result;
1915 }
1916 #endif /* defined(ENABLE_JIT) */
1917
1918
1919 /* exceptions_print_exception **************************************************
1920
1921    Prints an exception, the detail message and the cause, if
1922    available, with CACAO internal functions to stdout.
1923
1924 *******************************************************************************/
1925
1926 void exceptions_print_exception(java_handle_t *xptr)
1927 {
1928         java_lang_Throwable   *t;
1929 #if defined(ENABLE_JAVASE)
1930         java_lang_Throwable   *cause;
1931 #endif
1932         java_lang_String      *s;
1933         classinfo             *c;
1934         utf                   *u;
1935
1936         t = (java_lang_Throwable *) xptr;
1937
1938         if (t == NULL) {
1939                 puts("NULL\n");
1940                 return;
1941         }
1942
1943 #if defined(ENABLE_JAVASE)
1944         LLNI_field_get_ref(t, cause, cause);
1945 #endif
1946
1947         /* print the root exception */
1948
1949         LLNI_class_get(t, c);
1950         utf_display_printable_ascii_classname(c->name);
1951
1952         LLNI_field_get_ref(t, detailMessage, s);
1953
1954         if (s != NULL) {
1955                 u = javastring_toutf((java_handle_t *) s, false);
1956
1957                 printf(": ");
1958                 utf_display_printable_ascii(u);
1959         }
1960
1961         putc('\n', stdout);
1962
1963 #if defined(ENABLE_JAVASE)
1964         /* print the cause if available */
1965
1966         if ((cause != NULL) && (cause != t)) {
1967                 printf("Caused by: ");
1968                 
1969                 LLNI_class_get(cause, c);
1970                 utf_display_printable_ascii_classname(c->name);
1971
1972                 LLNI_field_get_ref(cause, detailMessage, s);
1973
1974                 if (s != NULL) {
1975                         u = javastring_toutf((java_handle_t *) s, false);
1976
1977                         printf(": ");
1978                         utf_display_printable_ascii(u);
1979                 }
1980
1981                 putc('\n', stdout);
1982         }
1983 #endif
1984 }
1985
1986
1987 /* exceptions_print_current_exception ******************************************
1988
1989    Prints the current pending exception, the detail message and the
1990    cause, if available, with CACAO internal functions to stdout.
1991
1992 *******************************************************************************/
1993
1994 void exceptions_print_current_exception(void)
1995 {
1996         java_handle_t *o;
1997
1998         o = exceptions_get_exception();
1999
2000         exceptions_print_exception(o);
2001 }
2002
2003
2004 /* exceptions_print_stacktrace *************************************************
2005
2006    Prints a pending exception with Throwable.printStackTrace().  If
2007    there happens an exception during printStackTrace(), we print the
2008    thrown exception and the original one.
2009
2010    NOTE: This function calls Java code.
2011
2012 *******************************************************************************/
2013
2014 void exceptions_print_stacktrace(void)
2015 {
2016         java_handle_t    *e;
2017         java_handle_t    *ne;
2018         classinfo        *c;
2019         methodinfo       *m;
2020
2021 #if defined(ENABLE_THREADS)
2022         threadobject     *t;
2023         java_lang_Thread *to;
2024 #endif
2025
2026         /* Get and clear exception because we are calling Java code
2027            again. */
2028
2029         e = exceptions_get_and_clear_exception();
2030
2031         if (e == NULL)
2032                 return;
2033
2034 #if 0
2035         /* FIXME Enable me. */
2036         if (builtin_instanceof(e, class_java_lang_ThreadDeath)) {
2037                 /* Don't print anything if we are being killed. */
2038         }
2039         else
2040 #endif
2041         {
2042                 /* Get the exception class. */
2043
2044                 LLNI_class_get(e, c);
2045
2046                 /* Find the printStackTrace() method. */
2047
2048                 m = class_resolveclassmethod(c,
2049                                                                          utf_printStackTrace,
2050                                                                          utf_void__void,
2051                                                                          class_java_lang_Object,
2052                                                                          false);
2053
2054                 if (m == NULL)
2055                         vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
2056
2057                 /* Print message. */
2058
2059                 fprintf(stderr, "Exception ");
2060
2061 #if defined(ENABLE_THREADS)
2062                 /* Print thread name.  We get the thread here explicitly as we
2063                    need it afterwards. */
2064
2065                 t  = thread_get_current();
2066                 to = (java_lang_Thread *) thread_get_object(t);
2067
2068                 if (to != NULL) {
2069                         fprintf(stderr, "in thread \"");
2070                         thread_fprint_name(t, stderr);
2071                         fprintf(stderr, "\" ");
2072                 }
2073 #endif
2074
2075                 /* Print the stacktrace. */
2076
2077                 if (builtin_instanceof(e, class_java_lang_Throwable)) {
2078                         (void) vm_call_method(m, e);
2079
2080                         /* If this happens we are EXTREMLY out of memory or have a
2081                            serious problem while printStackTrace.  But may be
2082                            another exception, so print it. */
2083
2084                         ne = exceptions_get_exception();
2085
2086                         if (ne != NULL) {
2087                                 fprintf(stderr, "Exception while printStackTrace(): ");
2088
2089                                 /* Print the current exception. */
2090
2091                                 exceptions_print_exception(ne);
2092                                 stacktrace_print_exception(ne);
2093
2094                                 /* Now print the original exception. */
2095
2096                                 fprintf(stderr, "Original exception was: ");
2097                                 exceptions_print_exception(e);
2098                                 stacktrace_print_exception(e);
2099                         }
2100                 }
2101                 else {
2102                         fprintf(stderr, ". Uncaught exception of type ");
2103                         /* FIXME This prints to stdout. */
2104                         class_print(c);
2105                         fprintf(stderr, ".");
2106                 }
2107
2108                 fflush(stderr);
2109         }
2110 }
2111
2112
2113 /*
2114  * These are local overrides for various environment variables in Emacs.
2115  * Please do not remove this and leave it at the end of the file, where
2116  * Emacs will automagically detect them.
2117  * ---------------------------------------------------------------------
2118  * Local variables:
2119  * mode: c
2120  * indent-tabs-mode: t
2121  * c-basic-offset: 4
2122  * tab-width: 4
2123  * End:
2124  * vim:noexpandtab:sw=4:ts=4:
2125  */