bump product version to 4.1.6.2
[LibreOffice.git] / include / wntgcci / sehandler.hxx
blob2fabe486a45271de65d6057c6cb05cdb418d02e2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 // Provenance of this code unclear. From crosswin32-dtrans-mingw.diff,
4 // but from where it got there, I don't know.
7 #ifndef _SEHANDLER_HXX
8 #define _SEHANDLER_HXX
10 #ifndef __MINGW32__
11 #error This file should be included only in a MinGW compilation
12 #endif
14 #include <windows.h>
15 #include <setjmp.h>
17 #ifndef EH_UNWINDING
18 // See _EH_UNWINDING in MSVS9/VC/crt/src/except.inc
19 #define EH_UNWINDING 2
20 #endif
22 namespace {
23 class __SEHandler
25 public:
26 __SEHandler() {}
27 ~__SEHandler() {}
28 typedef int (*PF)(void *, LPEXCEPTION_POINTERS);
29 typedef void (*PH)(void *, LPEXCEPTION_POINTERS);
30 typedef void (*PN)(void *);
31 void Set(jmp_buf jb, void *pdata=NULL, PF pfilter=NULL, PH phandlerbody=NULL, PN pfinal=NULL)
33 __builtin_memcpy(m_jmpbuf, jb, sizeof(jmp_buf));
34 m_pData=pdata;
35 switch (reinterpret_cast<int>(pfilter))
37 default:
38 m_filter=pfilter;
39 break;
40 case EXCEPTION_CONTINUE_EXECUTION:
41 m_filter=DefaultFilterContinueExecution;
42 break;
43 case EXCEPTION_EXECUTE_HANDLER:
44 m_filter=DefaultFilterExecuteHandler;
45 break;
46 case EXCEPTION_CONTINUE_SEARCH:
47 m_filter=DefaultFilterContinueSearch;
48 break;
50 if (phandlerbody)
51 m_handlerbody=phandlerbody;
52 else
53 m_handlerbody=DefaultHandler;
54 if (pfinal)
55 m_final=pfinal;
56 else
57 m_final=DefaultFinal;
58 m_ER.pHandlerClass = this;
59 m_ER.hp = handler;
60 asm("movl %%fs:0, %%eax\n\t"
61 "movl %%eax, %0": : "m" (m_ER.prev): "%eax" );
62 asm("movl %0, %%eax\n\t"
63 "movl %%eax, %%fs:0": : "r" (&m_ER): "%eax" );
65 void Reset()
67 m_final(m_pData);
68 asm("movl %0, %%eax \n\t"
69 "movl %%eax, %%fs:0"
70 : : "m" (m_ER.prev): "%eax");
72 private:
73 __SEHandler(const __SEHandler&);
74 __SEHandler& operator=(const __SEHandler&);
75 struct _ER {
76 _ER* prev;
77 PEXCEPTION_HANDLER hp;
78 __SEHandler *pHandlerClass;
80 static EXCEPTION_DISPOSITION handler(struct _EXCEPTION_RECORD *pExceptionRecord,
81 void * EstablisherFrame,
82 struct _CONTEXT *ContextRecord,
83 void * /*DispatcherContext*/)
85 __SEHandler* pThis = reinterpret_cast< _ER * >(EstablisherFrame)->pHandlerClass;
86 if (pExceptionRecord->ExceptionFlags & EH_UNWINDING)
88 pThis->m_final(pThis->m_pData);
89 return ExceptionContinueSearch;
91 EXCEPTION_POINTERS ep={pExceptionRecord, ContextRecord};
92 switch (pThis->m_filter(pThis->m_pData, &ep))
94 case EXCEPTION_EXECUTE_HANDLER:
95 RtlUnwind(EstablisherFrame, &&__set_label, pExceptionRecord, 0);
96 __set_label:
97 pThis->m_handlerbody(pThis->m_pData, &ep);
98 ContextRecord->Ebp = pThis->m_jmpbuf[0];
99 ContextRecord->Eip = pThis->m_jmpbuf[1];
100 ContextRecord->Esp = pThis->m_jmpbuf[2];
101 return ExceptionContinueExecution;
102 case EXCEPTION_CONTINUE_SEARCH:
103 return ExceptionContinueSearch;
104 case EXCEPTION_CONTINUE_EXECUTION:
105 return ExceptionContinueExecution;
107 return ExceptionContinueExecution;
109 static int DefaultFilterContinueSearch(void *, LPEXCEPTION_POINTERS) { return EXCEPTION_CONTINUE_SEARCH; }
110 static int DefaultFilterContinueExecution(void *, LPEXCEPTION_POINTERS) { return EXCEPTION_CONTINUE_EXECUTION; }
111 static int DefaultFilterExecuteHandler(void *, LPEXCEPTION_POINTERS) { return EXCEPTION_EXECUTE_HANDLER; }
112 static void DefaultHandler(void *, LPEXCEPTION_POINTERS) {}
113 static void DefaultFinal(void *) {}
114 typedef int (*handler_p)(struct _EXCEPTION_RECORD *ExceptionRecord,
115 void * EstablisherFrame,
116 struct _CONTEXT *ContextRecord,
117 void * DispatcherContext);
118 _ER m_ER;
119 void *m_pData;
120 PN m_final;
121 PH m_handlerbody;
122 PF m_filter;
123 jmp_buf m_jmpbuf;
126 } // namespace {
128 #endif // _SEHANDLER_HXX