OSDN Git Service

* java/util/zip/natInflater.cc (inflate): Treat Z_BUF_ERROR as
[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 <stddef.h>
14 #include <stdlib.h>
15
16 #include <java/lang/Class.h>
17 #include <java/lang/NullPointerException.h>
18 #include <gcj/cni.h>
19 #include <jvm.h>
20
21 // eh-common.h needs gansidecl.h.
22 #include "gansidecl.h"
23 #include "eh-common.h"
24
25 typedef struct {
26   __eh_info eh_info;
27   void *value;
28 } java_eh_info;
29
30
31 /* Language-specific EH info pointer, throw routine, and language/version
32    info routines. All defined in libgcc2. */
33
34 extern "C" java_eh_info **__get_eh_info (); 
35 extern "C" void __throw () __attribute__ ((__noreturn__));
36 extern "C" void __sjthrow () __attribute__ ((__noreturn__));
37 extern "C" short __get_eh_table_version (void *table);
38 extern "C" short __get_eh_table_language (void *table);
39 extern "C" void *__get_eh_context ();
40
41 extern "C" void *
42 _Jv_type_matcher (java_eh_info *info, void* match_info, 
43                   void *exception_table)
44 {
45 #ifndef SJLJ_EXCEPTIONS
46   /* No exception table implies the old style mechanism, so don't check. */
47   if (exception_table != NULL
48       && __get_eh_table_language (exception_table) != EH_LANG_Java)
49     return NULL;
50 #endif
51
52   /* we don't worry about version info yet, there is only one version! */
53   
54   if (match_info != NULL)
55     {
56       // The match_info is either a (java::lang::Class*) or
57       // match_info is one more than a (Utf8Const*).
58       if (sizeof(void*) != sizeof(size_t))
59         abort();
60       size_t mi = (size_t) match_info;
61       if ((mi & 1) != 0)
62         match_info = _Jv_FindClass ((Utf8Const*) (mi - 1), NULL);
63       if (! _Jv_IsInstanceOf ((jobject) info->value, (jclass) match_info))
64         return NULL;
65     }
66
67   return info->value;
68 }
69
70 /* Compiler hook to return a pointer to java exception object. The value
71    is cleared, so if the exception needs to be rethrown, it should be set 
72    again */
73
74 extern "C" void *
75 _Jv_exception_info (void)
76 {
77   java_eh_info *info = *(__get_eh_info ());
78   void *ptr;
79
80   if (info == NULL)
81     abort ();
82
83   ptr = info->value;
84
85   /* clear the value so another throw is an error */
86   info->value = NULL;
87
88   return ptr;
89 }
90
91
92
93 /* Allocate an exception info structure for java. Called the first time
94    an exception is thrown. */
95
96 extern "C" void
97 _Jv_eh_alloc ()
98 {
99   /* FIXME: we should use _Jv_AllocBytes here.  However, libgcc2
100      apparently can sometimes free() this value itself.  */
101   java_eh_info *p = (java_eh_info *) malloc (sizeof (java_eh_info));
102   if (p == 0)
103     abort ();
104
105   p->value = 0;
106   java_eh_info ** info_ptr = __get_eh_info ();
107
108   /* There should NOT be an exception info pointer already. */
109   if (*info_ptr != NULL)
110     abort ();
111
112   *info_ptr = p;
113 }
114
115 /* Deallocate the current exception info structure. Called at shutdown time. */
116
117 extern "C" void
118 _Jv_eh_free ()
119 {
120   java_eh_info ** info_ptr = __get_eh_info ();
121   if (*info_ptr == NULL)
122     abort ();
123   
124   /* FIXME: ideally we should just let the GC handle this.  */
125   free (*info_ptr);
126   *info_ptr = NULL;
127 }
128
129 /* Initialize an __eh_info structure with this libraries matching info. */
130
131 extern "C" void
132 _Jv_setup_eh_info (__eh_info *)
133 {
134 }
135
136 /* Perform a throw, Java style. Throw will unwind through this call,
137    so there better not be any handlers or exception thrown here. */
138
139 extern "C" void
140 _Jv_Throw (void *value)
141 {
142   if (value == NULL)
143     value = (void *) new java::lang::NullPointerException ();
144   java_eh_info *ehinfo = *(__get_eh_info ());
145   if (ehinfo == NULL)
146     {
147       _Jv_eh_alloc ();
148       ehinfo = *(__get_eh_info ());
149     }
150   ehinfo->eh_info.match_function = (__eh_matcher) _Jv_type_matcher;
151   ehinfo->eh_info.language = EH_LANG_Java;
152   ehinfo->eh_info.version = 1;
153   ehinfo->value = value;
154
155 /* We're happy with setjmp/longjmp exceptions or region-based
156    exception handlers: entry points are provided here for both.  */
157 #ifdef SJLJ_EXCEPTIONS
158   __sjthrow ();
159 #else
160   __throw ();
161 #endif
162 }
163
164 #ifdef USE_WIN32_SIGNALLING
165
166 // This is a mangled version of _Jv_Throw and __sjthrow except
167 // rather than calling longjmp, it returns a pointer to the jmp buffer
168
169 extern "C" int *
170 win32_get_restart_frame (void *value)
171 {
172   struct eh_context *eh = (struct eh_context *)__get_eh_context ();
173   void ***dhc = &eh->dynamic_handler_chain;
174  
175   java_eh_info *ehinfo = *(__get_eh_info ());
176   if (ehinfo == NULL)
177     {
178       _Jv_eh_alloc ();
179       ehinfo = *(__get_eh_info ());
180     }
181   ehinfo->eh_info.match_function = (__eh_matcher) _Jv_type_matcher;
182   ehinfo->eh_info.language = EH_LANG_Java;
183   ehinfo->eh_info.version = 1;
184   ehinfo->value = value;
185
186   // FIXME: Run clean ups?
187
188   int *jmpbuf = (int*)&(*dhc)[2];
189
190   *dhc = (void**)(*dhc)[0];
191
192   return  jmpbuf;
193 }
194
195 #endif /* USE_WIN32_SIGNALLING */