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