OWLNext    7.0
Borland's Object Windows Library for the modern age
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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.