2 * msvcrt C++ exception handling
4 * Copyright 2002 Alexandre Julliard
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.
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.
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 Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #ifndef __MSVCRT_CPPEXCEPT_H
22 #define __MSVCRT_CPPEXCEPT_H
24 #include <pseh/pseh2.h>
26 /* Macros to define assembler functions somewhat portably */
28 #define __ASM_FUNC(name) ".def " __ASM_NAME(name) "; .scl 2; .type 32; .endef"
29 #define __ASM_NAME(name) "_" name
32 # define __ASM_GLOBAL_FUNC(name,code) \
33 __asm__( ".align 4\n\t" \
34 ".globl " __ASM_NAME(#name) "\n\t" \
35 __ASM_FUNC(#name) "\n" \
36 __ASM_NAME(#name) ":\n\t" \
39 # define __ASM_GLOBAL_FUNC(name,code) \
40 void __asm_dummy_##name(void) { \
42 ".globl " __ASM_NAME(#name) "\n\t" \
43 __ASM_FUNC(#name) "\n" \
44 __ASM_NAME(#name) ":\n\t" \
49 #define EH_NONCONTINUABLE 0x01
50 #define EH_UNWINDING 0x02
51 #define EH_EXIT_UNWIND 0x04
52 #define EH_STACK_INVALID 0x08
53 #define EH_NESTED_CALL 0x10
59 #pragma warning(disable:4733)
62 static inline EXCEPTION_REGISTRATION_RECORD
*__wine_push_frame( EXCEPTION_REGISTRATION_RECORD
*frame
)
64 frame
->Next
= (struct _EXCEPTION_REGISTRATION_RECORD
*)__readfsdword(0);
65 __writefsdword(0, (unsigned long)frame
);
69 static inline EXCEPTION_REGISTRATION_RECORD
*__wine_pop_frame( EXCEPTION_REGISTRATION_RECORD
*frame
)
71 __writefsdword(0, (unsigned long)frame
->Next
);
81 #define __TRY _SEH2_TRY
82 #define __EXCEPT(func) _SEH2_EXCEPT(func(_SEH2_GetExceptionInformation()))
83 #define __EXCEPT_PAGE_FAULT _SEH2_EXCEPT(_SEH2_GetExceptionCode() == STATUS_ACCESS_VIOLATION)
84 #define __EXCEPT_ALL _SEH2_EXCEPT(_SEH_EXECUTE_HANDLER)
85 #define __ENDTRY _SEH2_END
86 #define __FINALLY(func) _SEH2_FINALLY { func(!_SEH2_AbnormalTermination()); }
88 #define CXX_FRAME_MAGIC 0x19930520
89 #define CXX_EXCEPTION 0xe06d7363
91 typedef void (*vtable_ptr
)();
93 /* type_info object, see cpp.c for inplementation */
94 typedef struct __type_info
96 const vtable_ptr
*vtable
;
97 char *name
; /* Unmangled name, allocated lazily */
98 char mangled
[32]; /* Variable length, but we declare it large enough for static RTTI */
101 /* exception object */
102 typedef struct __exception
104 const vtable_ptr
*vtable
;
105 char *name
; /* Name of this exception, always a new copy for each object */
106 int do_free
; /* Whether to free 'name' in our dtor */
109 /* the exception frame used by CxxFrameHandler */
110 typedef struct __cxx_exception_frame
112 EXCEPTION_REGISTRATION_RECORD frame
; /* the standard exception frame */
115 } cxx_exception_frame
;
117 /* info about a single catch {} block */
118 typedef struct __catchblock_info
120 UINT flags
; /* flags (see below) */
121 type_info
*type_info
; /* C++ type caught by this block */
122 int offset
; /* stack offset to copy exception object to */
123 void (*handler
)(); /* catch block handler code */
125 #define TYPE_FLAG_CONST 1
126 #define TYPE_FLAG_VOLATILE 2
127 #define TYPE_FLAG_REFERENCE 8
129 /* info about a single try {} block */
130 typedef struct __tryblock_info
132 int start_level
; /* start trylevel of that block */
133 int end_level
; /* end trylevel of that block */
134 int catch_level
; /* initial trylevel of the catch block */
135 int catchblock_count
; /* count of catch blocks in array */
136 catchblock_info
*catchblock
; /* array of catch blocks */
139 /* info about the unwind handler for a given trylevel */
140 typedef struct __unwind_info
142 int prev
; /* prev trylevel unwind handler, to run after this one */
143 void (*handler
)(); /* unwind handler */
146 /* descriptor of all try blocks of a given function */
147 typedef struct __cxx_function_descr
149 UINT magic
; /* must be CXX_FRAME_MAGIC */
150 UINT unwind_count
; /* number of unwind handlers */
151 unwind_info
*unwind_table
; /* array of unwind handlers */
152 UINT tryblock_count
; /* number of try blocks */
153 tryblock_info
*tryblock
; /* array of try blocks */
155 } cxx_function_descr
;
157 typedef void (*cxx_copy_ctor
)(void);
159 /* offsets for computing the this pointer */
162 int this_offset
; /* offset of base class this pointer from start of object */
163 int vbase_descr
; /* offset of virtual base class descriptor */
164 int vbase_offset
; /* offset of this pointer offset in virtual base class descriptor */
167 /* complete information about a C++ type */
168 typedef struct __cxx_type_info
170 UINT flags
; /* flags (see CLASS_* flags below) */
171 const type_info
*type_info
; /* C++ type info */
172 this_ptr_offsets offsets
; /* offsets for computing the this pointer */
173 unsigned int size
; /* object size */
174 cxx_copy_ctor copy_ctor
; /* copy constructor */
176 #define CLASS_IS_SIMPLE_TYPE 1
177 #define CLASS_HAS_VIRTUAL_BASE_CLASS 4
179 /* table of C++ types that apply for a given object */
180 typedef struct __cxx_type_info_table
182 UINT count
; /* number of types */
183 const cxx_type_info
*info
[3]; /* variable length, we declare it large enough for static RTTI */
184 } cxx_type_info_table
;
186 typedef DWORD (*cxx_exc_custom_handler
)( PEXCEPTION_RECORD
, cxx_exception_frame
*,
187 PCONTEXT
, EXCEPTION_REGISTRATION_RECORD
**,
188 const cxx_function_descr
*, int nested_trylevel
,
189 EXCEPTION_REGISTRATION_RECORD
*nested_frame
, DWORD unknown3
);
191 /* type information for an exception object */
192 typedef struct __cxx_exception_type
194 UINT flags
; /* TYPE_FLAG flags */
195 void (*destructor
)(); /* exception object destructor */
196 cxx_exc_custom_handler custom_handler
; /* custom handler for this exception */
197 const cxx_type_info_table
*type_info_table
; /* list of types for this exception object */
198 } cxx_exception_type
;
200 void _CxxThrowException(exception
*,const cxx_exception_type
*);
202 static inline const char *dbgstr_type_info( const type_info
*info
)
204 if (!info
) return "{}";
205 return "{}";/*sprintf( "{vtable=%p name=%s (%s)}",
206 info->vtable, info->mangled, info->name ? info->name : "" );*/
209 /* compute the this pointer for a base class of a given type */
210 static inline void *get_this_pointer( const this_ptr_offsets
*off
, void *object
)
215 if (!object
) return NULL
;
216 this_ptr
= (char *)object
+ off
->this_offset
;
217 if (off
->vbase_descr
>= 0)
219 /* move this ptr to vbase descriptor */
220 this_ptr
= (char *)this_ptr
+ off
->vbase_descr
;
221 /* and fetch additional offset from vbase descriptor */
222 offset_ptr
= (int *)(*(char **)this_ptr
+ off
->vbase_offset
);
223 this_ptr
= (char *)this_ptr
+ *offset_ptr
;
228 #endif /* __MSVCRT_CPPEXCEPT_H */