- Remove KD APIs from stub HAL, they've been in kdcom for a while (merge from kd...
[reactos.git] / reactos / include / reactos / libs / pseh / framebased.h
1 /*
2 Copyright (c) 2004/2005 KJK::Hyperion
3
4 Permission is hereby granted, free of charge, to any person obtaining a
5 copy of this software and associated documentation files (the "Software"),
6 to deal in the Software without restriction, including without limitation
7 the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 and/or sell copies of the Software, and to permit persons to whom the
9 Software is furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 DEALINGS IN THE SOFTWARE.
21 */
22
23 #ifndef KJK_PSEH_FRAMEBASED_H_
24 #define KJK_PSEH_FRAMEBASED_H_
25
26 #include <pseh/framebased/internal.h>
27 #include <pseh/excpt.h>
28
29 #ifndef offsetof
30 # include <stddef.h>
31 #endif
32
33 unsigned long __cdecl DbgPrint(const char * format, ...);
34
35 /*
36 Fall back to non-optimal, non-native NLG implementation for environments
37 without their own (e.g., currently, kernel-mode ReactOS/Windows). THIS IS NOT
38 RECOMMENDED AND IT WILL BE DROPPED IN A FUTURE VERSION BECAUSE IT MAY CAUSE
39 SEVERE STACK CORRUPTION. REIMPLEMENT OR PORT YOUR COMPILER'S NATIVE NLG
40 IMPLEMENTATION INSTEAD.
41 */
42 #ifdef _SEH_NO_NATIVE_NLG
43 # include <pseh/setjmp.h>
44 #else
45 # include <setjmp.h>
46 # define _SEHLongJmp longjmp
47 # define _SEHSetJmp setjmp
48 # define _SEHJmpBuf_t jmp_buf
49 #endif
50
51 #ifdef __cplusplus
52 # define _SEH_INIT_CONST static const
53 #else
54 # define _SEH_INIT_CONST register const
55 #endif
56
57 typedef struct __SEHFrame
58 {
59 _SEHPortableFrame_t SEH_Header;
60 void * SEH_Locals;
61 }
62 _SEHFrame_t;
63
64 typedef struct __SEHTryLevel
65 {
66 _SEHPortableTryLevel_t ST_Header;
67 _SEHJmpBuf_t ST_JmpBuf;
68 }
69 _SEHTryLevel_t;
70
71 static __declspec(noreturn) __inline void __stdcall _SEHCompilerSpecificHandler
72 (
73 _SEHPortableTryLevel_t * trylevel
74 )
75 {
76 _SEHTryLevel_t * mytrylevel;
77 DbgPrint("_SEHCompilerSpecificHandler(%p)\n", trylevel);
78 mytrylevel = _SEH_CONTAINING_RECORD(trylevel, _SEHTryLevel_t, ST_Header);
79 _SEHLongJmp(mytrylevel->ST_JmpBuf, 1);
80 }
81
82 static const int _SEHScopeKind = 1;
83 static _SEHPortableFrame_t * const _SEHPortableFrame = 0;
84
85 /* SHARED LOCALS */
86 /* Access the locals for the current frame */
87 #define _SEH_ACCESS_LOCALS(LOCALS_) \
88 _SEH_LOCALS_TYPENAME(LOCALS_) * _SEHPLocals; \
89 _SEHPLocals = \
90 _SEH_PVOID_CAST \
91 ( \
92 _SEH_LOCALS_TYPENAME(LOCALS_) *, \
93 _SEH_CONTAINING_RECORD(_SEHPortableFrame, _SEHFrame_t, SEH_Header) \
94 ->SEH_Locals \
95 );
96
97 /* Access local variable VAR_ */
98 #define _SEH_VAR(VAR_) _SEHPLocals->VAR_
99
100 /* FILTER FUNCTIONS */
101 /* Declares a filter function's prototype */
102 #define _SEH_FILTER(NAME_) \
103 long __stdcall NAME_ \
104 ( \
105 struct _EXCEPTION_POINTERS * _SEHExceptionPointers, \
106 struct __SEHPortableFrame * _SEHPortableFrame \
107 )
108
109 /* Declares a static filter */
110 #define _SEH_STATIC_FILTER(ACTION_) ((_SEHFilter_t)((ACTION_) + 2))
111
112 /* Declares a PSEH filter wrapping a regular filter function */
113 #define _SEH_WRAP_FILTER(WRAPPER_, NAME_) \
114 static __inline _SEH_FILTER(WRAPPER_) \
115 { \
116 return (NAME_)(_SEHExceptionPointers); \
117 }
118
119 /* FINALLY FUNCTIONS */
120 /* Declares a finally function's prototype */
121 #define _SEH_FINALLYFUNC(NAME_) \
122 void __stdcall NAME_ \
123 ( \
124 struct __SEHPortableFrame * _SEHPortableFrame \
125 )
126
127 /* Declares a PSEH finally function wrapping a regular function */
128 #define _SEH_WRAP_FINALLY(WRAPPER_, NAME_) \
129 _SEH_WRAP_FINALLY_ARGS(WRAPPER_, NAME_, ())
130
131 #define _SEH_WRAP_FINALLY_ARGS(WRAPPER_, NAME_, ARGS_) \
132 static __inline _SEH_FINALLYFUNC(WRAPPER_) \
133 { \
134 NAME_ ARGS_; \
135 }
136
137 #define _SEH_WRAP_FINALLY_LOCALS_ARGS(WRAPPER_, LOCALS_, NAME_, ARGS_) \
138 static __inline _SEH_FINALLYFUNC(WRAPPER_) \
139 { \
140 _SEH_ACCESS_LOCALS(LOCALS_); \
141 NAME_ ARGS_; \
142 }
143
144 /* SAFE BLOCKS */
145 #define _SEHX_TRY_FINALLY(FINALLY_) \
146 _SEH_TRY_FILTER_FINALLY \
147 ( \
148 _SEH_STATIC_FILTER(_SEH_CONTINUE_SEARCH), \
149 (FINALLY_) \
150 )
151
152 #define _SEHX_END_FINALLY _SEH_HANDLE _SEH_END
153
154 #define _SEHX_TRY_FILTER(FILTER_) \
155 _SEH_TRY_FILTER_FINALLY((FILTER_), 0)
156
157 #define _SEHX_TRY_HANDLE_FINALLY(FINALLY_) \
158 _SEH_TRY_FILTER_FINALLY \
159 ( \
160 _SEH_STATIC_FILTER(_SEH_EXECUTE_HANDLER), \
161 (FINALLY_) \
162 )
163
164 #define _SEHX_TRY \
165 _SEH_TRY_HANDLE_FINALLY(0)
166
167 #ifdef __cplusplus
168 # define _SEH_DECLARE_HANDLERS(FILTER_, FINALLY_) \
169 static const _SEHHandlers_t _SEHHandlers = { (FILTER_), (FINALLY_) };
170 #else
171 # define _SEH_DECLARE_HANDLERS(FILTER_, FINALLY_) \
172 _SEHHandlers_t _SEHHandlers = { (0), (0) }; \
173 _SEHHandlers.SH_Filter = (FILTER_); \
174 _SEHHandlers.SH_Finally = (FINALLY_);
175 #endif
176
177 #define _SEHX_TRY_FILTER_FINALLY(FILTER_, FINALLY_) \
178 { \
179 _SEHPortableFrame_t * const _SEHCurPortableFrame = _SEHPortableFrame; \
180 \
181 { \
182 _SEHFrame_t _SEHFrame; \
183 _SEHTryLevel_t _SEHTryLevel; \
184 _SEHPortableFrame_t * const _SEHPortableFrame = \
185 _SEHScopeKind ? &_SEHFrame.SEH_Header : _SEHCurPortableFrame; \
186 \
187 (void)_SEHPortableFrame; \
188 \
189 _SEH_DECLARE_HANDLERS((FILTER_), (FINALLY_)); \
190 \
191 _SEHTryLevel.ST_Header.SPT_Handlers = &_SEHHandlers; \
192 \
193 if(_SEHScopeKind) \
194 { \
195 if(&_SEHLocals != _SEHDummyLocals) \
196 _SEHFrame.SEH_Locals = &_SEHLocals; \
197 \
198 _SEHFrame.SEH_Header.SPF_Handler = _SEHCompilerSpecificHandler; \
199 _SEHEnterFrame(&_SEHFrame.SEH_Header, &_SEHTryLevel.ST_Header); \
200 } \
201 else \
202 _SEHEnterTry(&_SEHTryLevel.ST_Header); \
203 \
204 { \
205 _SEH_INIT_CONST int _SEHScopeKind = 0; \
206 (void)_SEHScopeKind; \
207 \
208 if(_SEHSetJmp(_SEHTryLevel.ST_JmpBuf) == 0) \
209 { \
210 for(;;) \
211 {
212
213 #define _SEHX_HANDLE \
214 \
215 break; \
216 } \
217 \
218 _SEHLeave(); \
219 } \
220 else \
221 { \
222 _SEHLeave();
223
224 #define _SEHX_END \
225 } \
226 \
227 if(_SEHHandlers.SH_Finally) \
228 _SEHHandlers.SH_Finally(_SEHPortableFrame); \
229 } \
230 } \
231 }
232
233 #define _SEHX_LEAVE break
234
235 #define _SEHX_GetExceptionCode() (unsigned long)(_SEHPortableFrame->SPF_Code)
236
237 #define _SEHX_GetExceptionPointers() \
238 ((struct _EXCEPTION_POINTERS *)_SEHExceptionPointers)
239
240 #define _SEHX_AbnormalTermination() (_SEHPortableFrame->SPF_Code != 0)
241
242 /* New syntax */
243
244 #define _SEH_LEAVE break
245
246 #define _SEH_TRY \
247 { \
248 _SEH_INIT_CONST int _SEHTopTryLevel = (_SEHScopeKind != 0); \
249 _SEHPortableFrame_t * const _SEHCurPortableFrame = _SEHPortableFrame; \
250 \
251 { \
252 _SEH_INIT_CONST int _SEHScopeKind = 0; \
253 register int _SEHState = 0; \
254 register int _SEHHandle = 0; \
255 _SEHFrame_t _SEHFrame; \
256 _SEHTryLevel_t _SEHTryLevel; \
257 _SEHPortableFrame_t * const _SEHPortableFrame = \
258 _SEHTopTryLevel ? &_SEHFrame.SEH_Header : _SEHCurPortableFrame; \
259 \
260 (void)_SEHScopeKind; \
261 (void)_SEHPortableFrame; \
262 (void)_SEHHandle; \
263 \
264 for(;;) \
265 { \
266 if(_SEHState) \
267 { \
268 for(;;) \
269 { \
270 {
271
272 #define _SEH_EXCEPT(FILTER_) \
273 } \
274 \
275 break; \
276 } \
277 \
278 break; \
279 } \
280 else \
281 { \
282 _SEH_DECLARE_HANDLERS((FILTER_), 0); \
283 \
284 _SEHTryLevel.ST_Header.SPT_Handlers = &_SEHHandlers; \
285 \
286 if(_SEHTopTryLevel) \
287 { \
288 if(&_SEHLocals != _SEHDummyLocals) \
289 _SEHFrame.SEH_Locals = &_SEHLocals; \
290 \
291 _SEH_EnableTracing(_SEH_DO_DEFAULT_TRACING); \
292 _SEHFrame.SEH_Header.SPF_Handler = _SEHCompilerSpecificHandler; \
293 _SEHEnterFrame(&_SEHFrame.SEH_Header, &_SEHTryLevel.ST_Header); \
294 } \
295 else \
296 _SEHEnterTry(&_SEHTryLevel.ST_Header); \
297 \
298 if((_SEHHandle = _SEHSetJmp(_SEHTryLevel.ST_JmpBuf)) == 0) \
299 { \
300 ++ _SEHState; \
301 continue; \
302 } \
303 else \
304 { \
305 break; \
306 } \
307 } \
308 \
309 break; \
310 } \
311 \
312 _SEHLeave(); \
313 \
314 if(_SEHHandle) \
315 {
316
317 #define _SEH_FINALLY(FINALLY_) \
318 } \
319 \
320 break; \
321 } \
322 \
323 _SEHLeave(); \
324 break; \
325 } \
326 else \
327 { \
328 _SEH_DECLARE_HANDLERS(0, (FINALLY_)); \
329 \
330 _SEHTryLevel.ST_Header.SPT_Handlers = &_SEHHandlers; \
331 \
332 if(_SEHTopTryLevel) \
333 { \
334 if(&_SEHLocals != _SEHDummyLocals) \
335 _SEHFrame.SEH_Locals = &_SEHLocals; \
336 \
337 _SEH_EnableTracing(_SEH_DO_DEFAULT_TRACING); \
338 _SEHFrame.SEH_Header.SPF_Handler = 0; \
339 _SEHEnterFrame(&_SEHFrame.SEH_Header, &_SEHTryLevel.ST_Header); \
340 } \
341 else \
342 _SEHEnterTry(&_SEHTryLevel.ST_Header); \
343 \
344 ++ _SEHState; \
345 continue; \
346 } \
347 \
348 break; \
349 } \
350 \
351 (FINALLY_)(&_SEHFrame.SEH_Header); \
352 \
353 if(0) \
354 {
355
356 #define _SEH_END \
357 } \
358 } \
359 }
360
361 #define _SEH_HANDLE _SEH_EXCEPT(_SEH_STATIC_FILTER(_SEH_EXECUTE_HANDLER))
362
363 #define _SEH_GetExceptionCode _SEHX_GetExceptionCode
364 #define _SEH_GetExceptionPointers _SEHX_GetExceptionPointers
365 #define _SEH_AbnormalTermination _SEHX_AbnormalTermination
366
367 #define _SEH_EnableTracing(LEVEL_) ((void)(_SEHPortableFrame->SPF_Tracing = (LEVEL_)))
368 #define _SEH_DisableTracing() ((void)(_SEHPortableFrame->SPF_Tracing = _SEH_DO_TRACE_NONE))
369
370 #endif
371
372 /* EOF */