VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Wine/include/wine/exception.h@ 28475

Last change on this file since 28475 was 28475, checked in by vboxsync, 15 years ago

crOpenGL: update to wine 1.1.43

  • Property svn:eol-style set to native
File size: 9.4 KB
Line 
1/*
2 * Wine exception handling
3 *
4 * Copyright (c) 1999 Alexandre Julliard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21/*
22 * Sun LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
23 * other than GPL or LGPL is available it will apply instead, Sun elects to use only
24 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
25 * a choice of LGPL license versions is made available with the language indicating
26 * that LGPLv2 or any later version may be used, or where a choice of which version
27 * of the LGPL is applied is otherwise unspecified.
28 */
29
30#ifndef __WINE_WINE_EXCEPTION_H
31#define __WINE_WINE_EXCEPTION_H
32
33#include <setjmp.h>
34#include <windef.h>
35#include <excpt.h>
36
37#ifdef __cplusplus
38extern "C" {
39#endif
40
41/* The following definitions allow using exceptions in Wine and Winelib code
42 *
43 * They should be used like this:
44 *
45 * __TRY
46 * {
47 * do some stuff that can raise an exception
48 * }
49 * __EXCEPT(filter_func)
50 * {
51 * handle the exception here
52 * }
53 * __ENDTRY
54 *
55 * or
56 *
57 * __TRY
58 * {
59 * do some stuff that can raise an exception
60 * }
61 * __FINALLY(finally_func)
62 *
63 * The filter_func and finally_func functions must be defined like this:
64 *
65 * LONG CALLBACK filter_func( PEXCEPTION_POINTERS __eptr ) { ... }
66 *
67 * void CALLBACK finally_func( BOOL __normal ) { ... }
68 *
69 * The filter function must return one of the EXCEPTION_* code; it can
70 * use GetExceptionInformation() and GetExceptionCode() to retrieve the
71 * exception info.
72 *
73 * Warning: inside a __TRY or __EXCEPT block, 'break' or 'continue' statements
74 * break out of the current block. You cannot use 'return', 'goto'
75 * or 'longjmp' to leave a __TRY block, as this will surely crash.
76 * You can use them to leave a __EXCEPT block though.
77 *
78 * -- AJ
79 */
80
81/* Define this if you want to use your compiler built-in __try/__except support.
82 * This is only useful when compiling to a native Windows binary, as the built-in
83 * compiler exceptions will most certainly not work under Winelib.
84 */
85#ifdef USE_COMPILER_EXCEPTIONS
86
87#define __TRY __try
88#define __EXCEPT(func) __except((func)(GetExceptionInformation()))
89#define __FINALLY(func) __finally { (func)(!AbnormalTermination()); }
90#define __ENDTRY /*nothing*/
91#define __EXCEPT_PAGE_FAULT __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
92#define __EXCEPT_ALL __except(EXCEPTION_EXECUTE_HANDLER)
93
94#else /* USE_COMPILER_EXCEPTIONS */
95
96#ifndef __GNUC__
97#define __attribute__(x) /* nothing */
98#endif
99
100#if defined(__MINGW32__) || defined(__CYGWIN__)
101#define sigjmp_buf jmp_buf
102#define sigsetjmp(buf,sigs) setjmp(buf)
103#define siglongjmp(buf,val) longjmp(buf,val)
104#endif
105
106extern void __wine_rtl_unwind( EXCEPTION_REGISTRATION_RECORD* frame, EXCEPTION_RECORD *record,
107 void (*target)(void) ) DECLSPEC_HIDDEN DECLSPEC_NORETURN;
108extern DWORD __wine_exception_handler( EXCEPTION_RECORD *record,
109 EXCEPTION_REGISTRATION_RECORD *frame,
110 CONTEXT *context,
111 EXCEPTION_REGISTRATION_RECORD **pdispatcher ) DECLSPEC_HIDDEN;
112extern DWORD __wine_exception_handler_page_fault( EXCEPTION_RECORD *record,
113 EXCEPTION_REGISTRATION_RECORD *frame,
114 CONTEXT *context,
115 EXCEPTION_REGISTRATION_RECORD **pdispatcher ) DECLSPEC_HIDDEN;
116extern DWORD __wine_exception_handler_all( EXCEPTION_RECORD *record,
117 EXCEPTION_REGISTRATION_RECORD *frame,
118 CONTEXT *context,
119 EXCEPTION_REGISTRATION_RECORD **pdispatcher ) DECLSPEC_HIDDEN;
120extern DWORD __wine_finally_handler( EXCEPTION_RECORD *record,
121 EXCEPTION_REGISTRATION_RECORD *frame,
122 CONTEXT *context,
123 EXCEPTION_REGISTRATION_RECORD **pdispatcher ) DECLSPEC_HIDDEN;
124
125#define __TRY \
126 do { __WINE_FRAME __f; \
127 int __first = 1; \
128 for (;;) if (!__first) \
129 { \
130 do {
131
132#define __EXCEPT(func) \
133 } while(0); \
134 __wine_pop_frame( &__f.frame ); \
135 break; \
136 } else { \
137 __f.frame.Handler = __wine_exception_handler; \
138 __f.u.filter = (func); \
139 if (sigsetjmp( __f.jmp, 0 )) { \
140 const __WINE_FRAME * const __eptr __attribute__((unused)) = &__f; \
141 do {
142
143/* convenience handler for page fault exceptions */
144#define __EXCEPT_PAGE_FAULT \
145 } while(0); \
146 __wine_pop_frame( &__f.frame ); \
147 break; \
148 } else { \
149 __f.frame.Handler = __wine_exception_handler_page_fault; \
150 if (sigsetjmp( __f.jmp, 0 )) { \
151 const __WINE_FRAME * const __eptr __attribute__((unused)) = &__f; \
152 do {
153
154/* convenience handler for all exception */
155#define __EXCEPT_ALL \
156 } while(0); \
157 __wine_pop_frame( &__f.frame ); \
158 break; \
159 } else { \
160 __f.frame.Handler = __wine_exception_handler_all; \
161 if (sigsetjmp( __f.jmp, 0 )) { \
162 const __WINE_FRAME * const __eptr __attribute__((unused)) = &__f; \
163 do {
164
165#define __ENDTRY \
166 } while (0); \
167 break; \
168 } \
169 __wine_push_frame( &__f.frame ); \
170 __first = 0; \
171 } \
172 } while (0);
173
174#define __FINALLY(func) \
175 } while(0); \
176 __wine_pop_frame( &__f.frame ); \
177 (func)(1); \
178 break; \
179 } else { \
180 __f.frame.Handler = __wine_finally_handler; \
181 __f.u.finally_func = (func); \
182 __wine_push_frame( &__f.frame ); \
183 __first = 0; \
184 } \
185 } while (0);
186
187
188typedef LONG (CALLBACK *__WINE_FILTER)(PEXCEPTION_POINTERS);
189typedef void (CALLBACK *__WINE_FINALLY)(BOOL);
190
191#define GetExceptionInformation() (__eptr)
192#define GetExceptionCode() (__eptr->ExceptionRecord->ExceptionCode)
193#define AbnormalTermination() (!__normal)
194
195typedef struct __tagWINE_FRAME
196{
197 EXCEPTION_REGISTRATION_RECORD frame;
198 union
199 {
200 /* exception data */
201 __WINE_FILTER filter;
202 /* finally data */
203 __WINE_FINALLY finally_func;
204 } u;
205 sigjmp_buf jmp;
206 /* hack to make GetExceptionCode() work in handler */
207 DWORD ExceptionCode;
208 const struct __tagWINE_FRAME *ExceptionRecord;
209} __WINE_FRAME;
210
211#endif /* USE_COMPILER_EXCEPTIONS */
212
213static inline EXCEPTION_REGISTRATION_RECORD *__wine_push_frame( EXCEPTION_REGISTRATION_RECORD *frame )
214{
215#if defined(__GNUC__) && defined(__i386__)
216 EXCEPTION_REGISTRATION_RECORD *prev;
217 __asm__ __volatile__(".byte 0x64\n\tmovl (0),%0"
218 "\n\tmovl %0,(%1)"
219 "\n\t.byte 0x64\n\tmovl %1,(0)"
220 : "=&r" (prev) : "r" (frame) : "memory" );
221 return prev;
222#else
223 NT_TIB *teb = (NT_TIB *)NtCurrentTeb();
224 frame->Prev = teb->ExceptionList;
225 teb->ExceptionList = frame;
226 return frame->Prev;
227#endif
228}
229
230static inline EXCEPTION_REGISTRATION_RECORD *__wine_pop_frame( EXCEPTION_REGISTRATION_RECORD *frame )
231{
232#if defined(__GNUC__) && defined(__i386__)
233 __asm__ __volatile__(".byte 0x64\n\tmovl %0,(0)"
234 : : "r" (frame->Prev) : "memory" );
235 return frame->Prev;
236
237#else
238 NT_TIB *teb = (NT_TIB *)NtCurrentTeb();
239 teb->ExceptionList = frame->Prev;
240 return frame->Prev;
241#endif
242}
243
244static inline EXCEPTION_REGISTRATION_RECORD *__wine_get_frame(void)
245{
246#if defined(__GNUC__) && defined(__i386__)
247 EXCEPTION_REGISTRATION_RECORD *ret;
248 __asm__ __volatile__(".byte 0x64\n\tmovl (0),%0" : "=r" (ret) );
249 return ret;
250#else
251 NT_TIB *teb = (NT_TIB *)NtCurrentTeb();
252 return teb->ExceptionList;
253#endif
254}
255
256/* Exception handling flags - from OS/2 2.0 exception handling */
257
258/* Win32 seems to use the same flags as ExceptionFlags in an EXCEPTION_RECORD */
259#define EH_NONCONTINUABLE 0x01
260#define EH_UNWINDING 0x02
261#define EH_EXIT_UNWIND 0x04
262#define EH_STACK_INVALID 0x08
263#define EH_NESTED_CALL 0x10
264
265/* Wine-specific exceptions codes */
266
267#define EXCEPTION_WINE_STUB 0x80000100 /* stub entry point called */
268#define EXCEPTION_WINE_ASSERTION 0x80000101 /* assertion failed */
269
270/* unhandled return status from vm86 mode */
271#define EXCEPTION_VM86_INTx 0x80000110
272#define EXCEPTION_VM86_STI 0x80000111
273#define EXCEPTION_VM86_PICRETURN 0x80000112
274
275extern void __wine_enter_vm86( CONTEXT *context );
276
277#ifdef __cplusplus
278}
279#endif
280
281#endif /* __WINE_WINE_EXCEPTION_H */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette