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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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
56 static inline EXCEPTION_REGISTRATION_RECORD
*__wine_push_frame( EXCEPTION_REGISTRATION_RECORD
*frame
)
59 frame
->Next
= (struct _EXCEPTION_REGISTRATION_RECORD
*)__readfsdword(0);
60 __writefsdword(0, (unsigned long)frame
);
63 NT_TIB
*teb
= (NT_TIB
*)NtCurrentTeb();
64 frame
->Next
= teb
->ExceptionList
;
65 teb
->ExceptionList
= frame
;
70 static inline EXCEPTION_REGISTRATION_RECORD
*__wine_pop_frame( EXCEPTION_REGISTRATION_RECORD
*frame
)
73 __writefsdword(0, (unsigned long)frame
->Next
);
76 NT_TIB
*teb
= (NT_TIB
*)NtCurrentTeb();
77 teb
->ExceptionList
= frame
->Next
;
83 #define __TRY _SEH2_TRY
84 #define __EXCEPT(func) _SEH2_EXCEPT(func(_SEH2_GetExceptionInformation()))
85 #define __EXCEPT_PAGE_FAULT _SEH2_EXCEPT(_SEH2_GetExceptionCode() == STATUS_ACCESS_VIOLATION)
86 #define __EXCEPT_ALL _SEH2_EXCEPT(_SEH_EXECUTE_HANDLER)
87 #define __ENDTRY _SEH2_END
88 #define __FINALLY(func) _SEH2_FINALLY { func(!_SEH2_AbnormalTermination()); }
90 #define CXX_FRAME_MAGIC 0x19930520
91 #define CXX_EXCEPTION 0xe06d7363
93 typedef void (*vtable_ptr
)();
95 /* type_info object, see cpp.c for inplementation */
96 typedef struct __type_info
98 const vtable_ptr
*vtable
;
99 char *name
; /* Unmangled name, allocated lazily */
100 char mangled
[32]; /* Variable length, but we declare it large enough for static RTTI */
103 /* exception object */
104 typedef struct __exception
106 const vtable_ptr
*vtable
;
107 char *name
; /* Name of this exception, always a new copy for each object */
108 int do_free
; /* Whether to free 'name' in our dtor */
111 /* the exception frame used by CxxFrameHandler */
112 typedef struct __cxx_exception_frame
114 EXCEPTION_REGISTRATION_RECORD frame
; /* the standard exception frame */
117 } cxx_exception_frame
;
119 /* info about a single catch {} block */
120 typedef struct __catchblock_info
122 UINT flags
; /* flags (see below) */
123 type_info
*type_info
; /* C++ type caught by this block */
124 int offset
; /* stack offset to copy exception object to */
125 void (*handler
)(); /* catch block handler code */
127 #define TYPE_FLAG_CONST 1
128 #define TYPE_FLAG_VOLATILE 2
129 #define TYPE_FLAG_REFERENCE 8
131 /* info about a single try {} block */
132 typedef struct __tryblock_info
134 int start_level
; /* start trylevel of that block */
135 int end_level
; /* end trylevel of that block */
136 int catch_level
; /* initial trylevel of the catch block */
137 int catchblock_count
; /* count of catch blocks in array */
138 catchblock_info
*catchblock
; /* array of catch blocks */
141 /* info about the unwind handler for a given trylevel */
142 typedef struct __unwind_info
144 int prev
; /* prev trylevel unwind handler, to run after this one */
145 void (*handler
)(); /* unwind handler */
148 /* descriptor of all try blocks of a given function */
149 typedef struct __cxx_function_descr
151 UINT magic
; /* must be CXX_FRAME_MAGIC */
152 UINT unwind_count
; /* number of unwind handlers */
153 unwind_info
*unwind_table
; /* array of unwind handlers */
154 UINT tryblock_count
; /* number of try blocks */
155 tryblock_info
*tryblock
; /* array of try blocks */
157 } cxx_function_descr
;
159 typedef void (*cxx_copy_ctor
)(void);
161 /* offsets for computing the this pointer */
164 int this_offset
; /* offset of base class this pointer from start of object */
165 int vbase_descr
; /* offset of virtual base class descriptor */
166 int vbase_offset
; /* offset of this pointer offset in virtual base class descriptor */
169 /* complete information about a C++ type */
170 typedef struct __cxx_type_info
172 UINT flags
; /* flags (see CLASS_* flags below) */
173 const type_info
*type_info
; /* C++ type info */
174 this_ptr_offsets offsets
; /* offsets for computing the this pointer */
175 unsigned int size
; /* object size */
176 cxx_copy_ctor copy_ctor
; /* copy constructor */
178 #define CLASS_IS_SIMPLE_TYPE 1
179 #define CLASS_HAS_VIRTUAL_BASE_CLASS 4
181 /* table of C++ types that apply for a given object */
182 typedef struct __cxx_type_info_table
184 UINT count
; /* number of types */
185 const cxx_type_info
*info
[3]; /* variable length, we declare it large enough for static RTTI */
186 } cxx_type_info_table
;
188 typedef DWORD (*cxx_exc_custom_handler
)( PEXCEPTION_RECORD
, cxx_exception_frame
*,
189 PCONTEXT
, EXCEPTION_REGISTRATION_RECORD
**,
190 const cxx_function_descr
*, int nested_trylevel
,
191 EXCEPTION_REGISTRATION_RECORD
*nested_frame
, DWORD unknown3
);
193 /* type information for an exception object */
194 typedef struct __cxx_exception_type
196 UINT flags
; /* TYPE_FLAG flags */
197 void (*destructor
)(); /* exception object destructor */
198 cxx_exc_custom_handler custom_handler
; /* custom handler for this exception */
199 const cxx_type_info_table
*type_info_table
; /* list of types for this exception object */
200 } cxx_exception_type
;
202 void _CxxThrowException(exception
*,const cxx_exception_type
*);
204 static inline const char *dbgstr_type_info( const type_info
*info
)
206 if (!info
) return "{}";
207 return "{}";/*sprintf( "{vtable=%p name=%s (%s)}",
208 info->vtable, info->mangled, info->name ? info->name : "" );*/
211 /* compute the this pointer for a base class of a given type */
212 static inline void *get_this_pointer( const this_ptr_offsets
*off
, void *object
)
217 if (!object
) return NULL
;
218 this_ptr
= (char *)object
+ off
->this_offset
;
219 if (off
->vbase_descr
>= 0)
221 /* move this ptr to vbase descriptor */
222 this_ptr
= (char *)this_ptr
+ off
->vbase_descr
;
223 /* and fetch additional offset from vbase descriptor */
224 offset_ptr
= (int *)(*(char **)this_ptr
+ off
->vbase_offset
);
225 this_ptr
= (char *)this_ptr
+ *offset_ptr
;
230 #endif /* __MSVCRT_CPPEXCEPT_H */