]>
Commit | Line | Data |
---|---|---|
ee9dd372 TT |
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 | } | |
25fef12b | 150 | ehinfo->eh_info.match_function = (__eh_matcher) _Jv_type_matcher; |
ee9dd372 TT |
151 | ehinfo->eh_info.language = EH_LANG_Java; |
152 | ehinfo->eh_info.version = 1; | |
153 | ehinfo->value = value; | |
154 | __throw(); | |
155 | } |