OSDN Git Service

* All files: Updated copyright information.
[pf3gnuchains/gcc-fork.git] / libjava / exception.cc
1 // Functions for Exception Support for Java.
2
3 /* Copyright (C) 1998, 1999  Free Software Foundation
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 #include <config.h>
12
13 #include "exception"
14 #include <stddef.h>
15 #include <stdlib.h>
16
17 #include <java/lang/Class.h>
18 #include <java/lang/NullPointerException.h>
19 #include <gcj/cni.h>
20 #include <jvm.h>
21
22 // eh-common.h needs gansidecl.h.
23 #include "gansidecl.h"
24 #include "eh-common.h"
25
26 typedef struct {
27   __eh_info eh_info;
28   void *value;
29 } java_eh_info;
30
31
32 /* Language-specific EH info pointer, throw routine, and language/version
33    info routines. All defined in libgcc2. */
34
35 extern "C" java_eh_info **__get_eh_info (); 
36 extern "C" void __throw () __attribute__ ((__noreturn__));
37 extern "C" void __sjthrow () __attribute__ ((__noreturn__));
38 extern "C" short __get_eh_table_version (void *table);
39 extern "C" short __get_eh_table_language (void *table);
40
41
42 extern "C" void *
43 _Jv_type_matcher (java_eh_info *info, void* match_info, 
44                   void *exception_table)
45 {
46 #ifndef SJLJ_EXCEPTIONS
47   /* No exception table implies the old style mechanism, so don't check. */
48   if (exception_table != NULL
49       && __get_eh_table_language (exception_table) != EH_LANG_Java)
50     return NULL;
51 #endif
52
53   /* we don't worry about version info yet, there is only one version! */
54   
55   if (match_info != NULL)
56     {
57       // The match_info is either a (java::lang::Class*) or
58       // match_info is one more than a (Utf8Const*).
59       if (sizeof(void*) != sizeof(size_t))
60         abort();
61       size_t mi = (size_t) match_info;
62       if ((mi & 1) != 0)
63         match_info = _Jv_FindClass ((Utf8Const*) (mi - 1), NULL);
64       if (! _Jv_IsInstanceOf ((jobject) info->value, (jclass) match_info))
65         return NULL;
66     }
67
68   return info->value;
69 }
70
71 /* Compiler hook to return a pointer to java exception object. The value
72    is cleared, so if the exception needs to be rethrown, it should be set 
73    again */
74
75 extern "C" void *
76 _Jv_exception_info (void)
77 {
78   java_eh_info *info = *(__get_eh_info ());
79   void *ptr;
80
81   if (info == NULL)
82     abort ();
83
84   ptr = info->value;
85
86   /* clear the value so another throw is an error */
87   info->value = NULL;
88
89   return ptr;
90 }
91
92
93
94 /* Allocate an exception info structure for java. Called the first time
95    an exception is thrown. */
96
97 extern "C" void
98 _Jv_eh_alloc ()
99 {
100   /* FIXME: we should use _Jv_AllocBytes here.  However, libgcc2
101      apparently can sometimes free() this value itself.  */
102   java_eh_info *p = (java_eh_info *) malloc (sizeof (java_eh_info));
103   if (p == 0)
104     terminate ();
105
106   p->value = 0;
107   java_eh_info ** info_ptr = __get_eh_info ();
108
109   /* There should NOT be an exception info pointer already. */
110   if (*info_ptr != NULL)
111     abort ();
112
113   *info_ptr = p;
114 }
115
116 /* Deallocate the current exception info structure. Called at shutdown time. */
117
118 extern "C" void
119 _Jv_eh_free ()
120 {
121   java_eh_info ** info_ptr = __get_eh_info ();
122   if (*info_ptr == NULL)
123     abort ();
124   
125   /* FIXME: ideally we should just let the GC handle this.  */
126   free (*info_ptr);
127   *info_ptr = NULL;
128 }
129
130 /* Initialize an __eh_info structure with this libraries matching info. */
131
132 extern "C" void
133 _Jv_setup_eh_info (__eh_info *)
134 {
135 }
136
137 /* Perform a throw, Java style. Throw will unwind through this call,
138    so there better not be any handlers or exception thrown here. */
139
140 extern "C" void
141 _Jv_Throw (void *value)
142 {
143   if (value == NULL)
144     value = (void *) new java::lang::NullPointerException ();
145   java_eh_info *ehinfo = *(__get_eh_info ());
146   if (ehinfo == NULL)
147     {
148       _Jv_eh_alloc ();
149       ehinfo = *(__get_eh_info ());
150     }
151   ehinfo->eh_info.match_function = (__eh_matcher) _Jv_type_matcher;
152   ehinfo->eh_info.language = EH_LANG_Java;
153   ehinfo->eh_info.version = 1;
154   ehinfo->value = value;
155
156 /* We're happy with setjmp/longjmp exceptions or region-based
157    exception handlers: entry points are provided here for both.  */
158 #ifdef SJLJ_EXCEPTIONS
159   __sjthrow ();
160 #else
161   __throw ();
162 #endif
163 }