ServerSocket.java: Define ANY_IF.
[gcc.git] / libjava / exception.cc
1 // Functions for Exception Support for Java.
2
3 /* Copyright (C) 1998, 1999 Cygnus Solutions
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
16 #include <java/lang/Class.h>
17 #include <java/lang/NullPointerException.h>
18 #include <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" short __get_eh_table_version (void *table);
37 extern "C" short __get_eh_table_language (void *table);
38
39
40 extern "C" void * malloc (size_t);
41 extern "C" void free (void *);
42
43
44 extern "C" void *
45 _Jv_type_matcher (java_eh_info *info, void* match_info,
46 void *exception_table)
47 {
48 if (__get_eh_table_language (exception_table) != EH_LANG_Java)
49 return NULL;
50
51 /* we don't worry about version info yet, there is only one version! */
52
53 if (match_info != NULL)
54 {
55 // The match_info is either a (java::lang::Class*) or
56 // match_info is one more than a (Utf8Const*).
57 if (sizeof(void*) != sizeof(size_t))
58 abort();
59 size_t mi = (size_t) match_info;
60 if ((mi & 1) != 0)
61 match_info = _Jv_FindClass ((Utf8Const*) (mi - 1), NULL);
62 if (! _Jv_IsInstanceOf ((jobject) info->value, (jclass) match_info))
63 return NULL;
64 }
65
66 return info->value;
67 }
68
69 /* Compiler hook to return a pointer to java exception object. The value
70 is cleared, so if the exception needs to be rethrown, it should be set
71 again */
72
73 extern "C" void *
74 _Jv_exception_info (void)
75 {
76 java_eh_info *info = *(__get_eh_info ());
77 void *ptr;
78
79 if (info == NULL)
80 abort ();
81
82 ptr = info->value;
83
84 /* clear the value so another throw is an error */
85 info->value = NULL;
86
87 return ptr;
88 }
89
90
91
92 /* Allocate an exception info structure for java. Called the first time
93 an exception is thrown. */
94
95 extern "C" void
96 _Jv_eh_alloc ()
97 {
98 /* FIXME: we should use _Jv_AllocBytes here. However, libgcc2
99 apparently can sometimes free() this value itself. */
100 java_eh_info *p = (java_eh_info *) malloc (sizeof (java_eh_info));
101 if (p == 0)
102 terminate ();
103
104 p->value = 0;
105 java_eh_info ** info_ptr = __get_eh_info ();
106
107 /* There should NOT be an exception info pointer already. */
108 if (*info_ptr != NULL)
109 abort ();
110
111 *info_ptr = p;
112 }
113
114 /* Deallocate the current exception info structure. Called at shutdown time. */
115
116 extern "C" void
117 _Jv_eh_free ()
118 {
119 java_eh_info ** info_ptr = __get_eh_info ();
120 if (*info_ptr == NULL)
121 abort ();
122
123 /* FIXME: ideally we should just let the GC handle this. */
124 free (*info_ptr);
125 *info_ptr = NULL;
126 }
127
128 /* Perform a throw, Java style. Throw will unwind through this call, so
129 there better not be any handlers or exception thrown here. */
130
131
132 /* Initialize an __eh_info structure with this libraries matching info. */
133
134 extern "C" void
135 _Jv_setup_eh_info (__eh_info *)
136 {
137 }
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 __throw();
155 }