OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
unixxcpt.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// ObjectWindows, OWL NExt
3// Created by Kenneth Haley ( khaley@bigfoot.com )
4//
5/// \file
6/// GNU support
7//----------------------------------------------------------------------------
8#define _EXCPT_H
9#define _EXCPT_H_
10
11#if !defined(MAINWIN) && !defined(WINELIB)
12
13#undef _OWLPCH
14#include <owl/window.h>
15#include <owl/registry.h>
16
17using namespace owl;
18
19#ifdef UNIX
20#include <pshpack8.h>
21#else
22/* winemaker: #pragma pack(push, 8) */
23#include <pshpack8.h>
24#endif
25
26extern "C" {
27
28/// \cond
29typedef struct _SCOPETABLE {
30 unsigned long previousTryLevel;
31 int __stdcall (*lpfnFilter)(); // address of filter function for this
32 // _try/_except 0 for finally
33 void __stdcall (*lpfnHandler)(); // address of _except _except_handler3
34 // returns here if EXCEPTION_EXECUTE_HANDLER
35 // in filter function
37
38
39typedef struct _VC_EXCEPTION_REGISTRATION {
40 unsigned long stan_stack;
41 unsigned long xcept_ptrs;
42 unsigned long prev;
43 unsigned long handler;
45 unsigned long trylevel;
46 unsigned long _ebp;
48/// \endcond
49
50}
51
52#define EH_NONCONTINUABLE 0x01
53#define EH_UNWINDING 0x02
54#define EH_EXIT_UNWIND 0x04
55#define EH_STACK_INVALID 0x08
56#define EH_NESTED_CALL 0x10
57
58#define EXCEPTION_EXECUTE_HANDLER 1
59//#define EXCEPTION_CONTINUE_EXECUTION -1
60#define EXCEPTION_CONTINUE_SEARCH 0
61
68
69// vc++ generated functions
70
71#define GetExceptionInformation() \
72__vcer.xcept_ptrs
73
74#define GetExceptionCode()\
75(**((int**)__vcer.xcept_ptrs))
76
77#define RpcExceptionCode() GetExceptionCode()
78
79//the above macros are only usable inside _try/_except block
80//gcc will not generate a warning if these are used
81//outside the _except block, but you will get garbage results
82
83#define _SXV(args...) \
84__asm__ __volatile__("/BEGIN_SXV\n"); \
85VC_EXCEPTION_REGISTRATION __vcer; \
86int __volatile__ __xcpt_filter_result __attribute__((__unused__)); \
87int __volatile__ __xcpt_happened __attribute__((__unused__)); \
88__asm__ __volatile__(".equ __except_list, 0\n"); \
89__vcer.trylevel=(unsigned long)-1; \
90__vcer.handler=(unsigned long)&mexcept_handler3; \
91__asm__ __volatile__("/END_SXV\n");
92
93#undef _try
94#define _try \
95__asm__ __volatile__(\
96"/ BEGIN_TRY\n\t"\
97"movl %%esp, %0;\n\t"\
98"movl %%ebp, %1;\n"\
99: "=g" (__vcer.stan_stack), "=g" (__vcer._ebp) : );\
100__asm__ __volatile__(\
101 "movl %%fs:__except_list,%0\n\t"\
102 "movl %2,%%fs:__except_list\n\t"\
103 "/ ScopeTable Pointer\n\t"\
104 "movl $5f,%1\n"\
105 : "=g" (__vcer.prev), "=m" (__vcer.tbl_ptr): "r" (&__vcer.prev) : "memory");\
106 ++__vcer.trylevel;\
107__asm__ __volatile__("/ END_TRY");\
108 if(1)
109//JJH
110#if defined(__GNUC__)
111#undef _except //(args...)
112#else
113#undef _except(args...)
114#endif //__GNUC__
115#define _except(args...) \
116__asm__ __volatile__("/BEGIN_EXCEPT\n");\
117__xcpt_happened = 0;\
118__asm__ __volatile__(\
119".section .rdata\n"\
120".align 16, 0x0\n\t"\
121 "5:.int -1, 1f, 2f\n"\
122".text\n\t"\
123 "jmp 2f\n"\
124 "1:\n");\
125__xcpt_filter_result = (## args);\
126__asm__ __volatile__(\
127 "cmpl $-1,%1\n\t"\
128 "je 4f\n\t"\
129 "incl %0\n\t"\
130 : "=m" (__xcpt_happened)\
131 : "a" (__xcpt_filter_result)\
132 );\
133__asm__ __volatile__(\
134 "4:ret\n\t"\
135 "2:\n"\
136 "/ reset __except_list to previous exception function\n\t"\
137 "movl %0,%%fs:__except_list\n" : : "r" (__vcer.prev) : "memory");\
138--__vcer.trylevel;\
139__asm__ __volatile__("/END_EXCEPT\n");\
140if(__xcpt_happened && (## args))
141
142#define __try _try
143#define __try__ _try
144#define __except _except
145#define __except__ _except
146
147#ifdef UNIX
148#include <poppack.h>
149#else
150/* winemaker: #pragma pack(pop) */
151#include <poppack.h>
152#endif
153
154extern "C" {
158 struct _CONTEXT* pContextRecord,
159 void*
160 );
161};
162#define TRYLEVEL_NONE -1
163extern "C" {
164 void _global_unwind2(void*);
165 void _local_unwind2(void*,int);
169 struct _CONTEXT* pContextRecord,
170 void*
171 );
172};
173
177 struct _CONTEXT* pContextRecord,
178 void *
179 )
180{
186
187
188 __asm__ __volatile__("cld"); // Clear the direction flag (make no assumptions!)
189
190 // if neither the EXCEPTION_UNWINDING nor EXCEPTION_EXIT_UNWIND bit
191 // is set... This is true the first time through the handler (the
192 // non-unwinding case)
193 if ( ! (pExceptionRecord->ExceptionFlags
195 ) )
196 {
197 // Build the EXCEPTION_POINTERS structure on the stack
198 exceptPtrs.ExceptionRecord = pExceptionRecord;
199 exceptPtrs.ContextRecord = pContextRecord;
200
201 // Put the pointer to the EXCEPTION_POINTERS 4 bytes below the
202 // establisher frame. See ASM code for GetExceptionInformation
203 __vcer->xcept_ptrs = (unsigned long)&exceptPtrs;
204
205 // Get initial "trylevel" value
206 trylevel = __vcer->trylevel ;
207
208 // Get a pointer to the scopetable array
209 pScopeTable = __vcer->tbl_ptr;
210
212 if ( trylevel != TRYLEVEL_NONE ){
214
215
216 // !!!Very Important!!! Switch to original EBP. This is
217 // what allows all locals in the frame to have the same
218 // value as before the exception occurred.
219
220
221 // Call the filter function
222 __asm__ __volatile__("pushl %%ebp\n\t"\
223 "movl %2,%%ebp\n\t"\
224 "call *%1\n\t"\
225 "popl %%ebp" : "=a" (filterFuncRet) \
226 : "r" (pScopeTable[trylevel].lpfnFilter), "m" (__vcer->_ebp) );
227
228
230 if ( filterFuncRet < 0 ) // EXCEPTION_CONTINUE_EXECUTION
232
233 // If we get here, EXCEPTION_EXECUTE_HANDLER was specified
234 //scopetable == pRegistrationFrame->scopetable
235
236 // Does the actual OS cleanup of registration frames
237 // Causes this function to recurse
239
240
241 // Once we get here, everything is all cleaned up, except
242 // for the last frame, where we'll continue execution
243 //PUSH EBP // Save EBP
244 //EBP = pRegistrationFrame->_ebp // Set EBP for __local_unwind2
245 //why???
246
248
249 // POP EBP
250
251 // Set the current trylevel to whatever SCOPETABLE entry
252 // was being used when a handler was found (why?)
253
254 __vcer->trylevel = pScopeTable->previousTryLevel;
255
256 // Call the _except {} block. Never returns.
257 //__vcer->tbl_ptr[trylevel].lpfnHandler();
258 // effectively a longjump
259
260 __asm__ __volatile__ ("pushfl\n\tpopl %%esi\n\t"\
261 "movl %0, %%esp\n\t"\
262 "movl %1, %%ebp\n\t"\
263 "pushl %2\n\t"\
264 "pushl %%esi\n\tpopfl\n\t"\
265 "ret": : "r" (__vcer->stan_stack), "r" (__vcer->_ebp), "r" (pScopeTable->lpfnHandler) );
266
267 }///continue search
268 }//filter
269 __vcer=(VC_EXCEPTION_REGISTRATION*)(((long*)__vcer->prev)-2);
270 trylevel = pScopeTable->previousTryLevel;
271 pScopeTable = __vcer->tbl_ptr;
272
274 }
275 else{ // trylevel == TRYLEVEL_NONE
276 //retvalue == DISPOSITION_CONTINUE_SEARCH;
278 }
279 }
280 else { // EXCEPTION_UNWINDING or EXCEPTION_EXIT_UNWIND flags are set
281// PUSH EBP // Save EBP
282// EBP = pRegistrationFrame->_ebp // Set EBP for __local_unwind2
283//why ???
284// __asm__ __volatile__("pushl %%ebp\n\tmovl %0,%%ebp": :"m" (__vcer->_ebp));
285
287
288// __asm__ __volatile__("pop %ebp"); // Restore EBP
289
290// retvalue == DISPOSITION_CONTINUE_SEARCH;
292 }
293}
294
295namespace owl {
296
298{
299 _SXV(;);
300 // use SEH (structured exception handling) to catch even GPFs
301 // that result from partially valid objects.
302 TDrawItem* item;
303 __try{
305 }
307 return 0;
308 }
309 return item;
310}
311
313:
314 Key(aliasKey),
315 Name(strnewdup(keyName))
316{
317 _SXV(;);
318 ShouldClose = shouldClose;
319
320 __try {
321 long err = QueryInfo(0, 0, &SubkeyCount, 0, 0, &ValueCount, 0, 0, 0, 0);
323 Key = 0;
324 }
325 // Some key handles are unsupported & sometimes the OS crashes, & doesn't
326 // just return an error. Catch it here & zero out this key.
327 //
330 {
331 Key = 0;
332 }
333}
334} // OWL namespace
335
336#endif //ifndef MAINWIN && !defined(WINELIB)
337/*===============================================================*/
Class will be base class for owner draw items: ListBox,ComboBox,Menu atc.
Definition window.h:178
TRegKey(THandle baseKey, tstring keyName, REGSAM samDesired=KEY_ALL_ACCESS, TCreateOK createOK=CreateOK)
Creates or opens a key given a base key and a subkey name.
Definition registry.cpp:128
char * strnewdup(const char *s, size_t minAllocSize=0)
Definition memory.cpp:25
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
TDrawItem * lTCB(uint32 data)
Definition unixxcpt.cpp:297
#define TYPESAFE_DOWNCAST(object, toClass)
Definition defs.h:269
General Registry access & registration implementation TRegKey, TRegValue, TRegKeyIterator,...
#define EH_EXIT_UNWIND
Definition unixxcpt.cpp:54
#define __try
Definition unixxcpt.cpp:142
#define TRYLEVEL_NONE
Definition unixxcpt.cpp:162
#define EXCEPTION_EXECUTE_HANDLER
Definition unixxcpt.cpp:58
EXCEPTION_DISPOSITION
Definition unixxcpt.cpp:62
@ ExceptionContinueSearch
Definition unixxcpt.cpp:64
@ ExceptionCollidedUnwind
Definition unixxcpt.cpp:66
@ ExceptionNestedException
Definition unixxcpt.cpp:65
@ ExceptionContinueExecution
Definition unixxcpt.cpp:63
#define __except
Definition unixxcpt.cpp:144
#define _SXV(args...)
Definition unixxcpt.cpp:83
#define EXCEPTION_CONTINUE_SEARCH
Definition unixxcpt.cpp:60
#define EH_UNWINDING
Definition unixxcpt.cpp:53
int mexcept_handler3(struct _EXCEPTION_RECORD *pExceptionRecord, VC_EXCEPTION_REGISTRATION *pRegistrationFrame, struct _CONTEXT *pContextRecord, void *)
Definition unixxcpt.cpp:174
void _local_unwind2(void *, int)
void _global_unwind2(void *)
#define GetExceptionCode()
Definition unixxcpt.cpp:74
Base window class TWindow definition, including HWND encapsulation.