ReactOS 0.4.16-dev-2104-gb84fa49
cppexcept.h
Go to the documentation of this file.
1/*
2 * msvcrt C++ exception handling
3 *
4 * Copyright 2002 Alexandre Julliard
5 *
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.
10 *
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.
15 *
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 St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#ifndef __MSVCRT_CPPEXCEPT_H
22#define __MSVCRT_CPPEXCEPT_H
23
24#include <fpieee.h>
25#include "cxx.h"
26
27#ifdef __REACTOS__
28#include "msvc_fwd_decl.h"
29#endif
30
31#define CXX_FRAME_MAGIC_VC6 0x19930520
32#define CXX_FRAME_MAGIC_VC7 0x19930521
33#define CXX_FRAME_MAGIC_VC8 0x19930522
34#define CXX_EXCEPTION 0xe06d7363
35
36typedef struct
37{
39 int state;
41
42#ifndef RTTI_USE_RVA
43
44#define CXX_EXCEPTION_PARAMS 3
45
46/* info about a single catch {} block */
47typedef struct
48{
49 UINT flags; /* flags (see below) */
50 const type_info *type_info; /* C++ type caught by this block */
51 int offset; /* stack offset to copy exception object to */
52 void * (*handler)(void);/* catch block handler code */
54
55/* info about a single try {} block */
56typedef struct
57{
58 int start_level; /* start trylevel of that block */
59 int end_level; /* end trylevel of that block */
60 int catch_level; /* initial trylevel of the catch block */
61 unsigned int catchblock_count; /* count of catch blocks in array */
62 const catchblock_info *catchblock; /* array of catch blocks */
64
65/* info about the unwind handler for a given trylevel */
66typedef struct
67{
68 int prev; /* prev trylevel unwind handler, to run after this one */
69 void * (*handler)(void);/* unwind handler */
71
72/* descriptor of all try blocks of a given function */
73typedef struct
74{
75 UINT magic : 29; /* must be CXX_FRAME_MAGIC */
76 UINT bbt_flags : 3;
77 UINT unwind_count; /* number of unwind handlers */
78 const unwind_info *unwind_table; /* array of unwind handlers */
79 UINT tryblock_count; /* number of try blocks */
80 const tryblock_info *tryblock; /* array of try blocks */
81 UINT ipmap_count;
82 const ipmap_info *ipmap;
83 const void *expect_list; /* expected exceptions list when magic >= VC7 */
84 UINT flags; /* flags when magic >= VC8 */
86
87#else /* RTTI_USE_RVA */
88
89#define CXX_EXCEPTION_PARAMS 4
90
91typedef struct
92{
95 int offset;
97#ifdef _WIN64
98 UINT frame;
99#endif
101
102typedef struct
103{
110
111typedef struct
112{
113 int prev;
116
117typedef struct
118{
131
132#endif /* RTTI_USE_RVA */
133
134#define FUNC_DESCR_SYNCHRONOUS 1 /* synchronous exceptions only (built with /EHs and /EHsc) */
135#define FUNC_DESCR_NOEXCEPT 4 /* noexcept function */
136
137#define CLASS_IS_SIMPLE_TYPE 1
138#define CLASS_HAS_VIRTUAL_BASE_CLASS 4
139
140#define TYPE_FLAG_CONST 1
141#define TYPE_FLAG_VOLATILE 2
142#define TYPE_FLAG_REFERENCE 8
143
145
147{
148 if (rec->ExceptionCode != CXX_EXCEPTION) return FALSE;
149 if (rec->NumberParameters != CXX_EXCEPTION_PARAMS) return FALSE;
150 return (rec->ExceptionInformation[0] >= CXX_FRAME_MAGIC_VC6 &&
152}
153
154typedef struct
155{
157 LONG *ref; /* not binary compatible with native msvcr100 */
159
160void throw_exception(const char*);
162
166
168
169static inline const char *dbgstr_type_info( const type_info *info )
170{
171 if (!info) return "{}";
172 return wine_dbg_sprintf( "{vtable=%p name=%s (%s)}",
173 info->vtable, info->mangled, info->name ? info->name : "" );
174}
175
176/* compute the this pointer for a base class of a given type */
177static inline void *get_this_pointer( const this_ptr_offsets *off, void *object )
178{
179 if (!object) return NULL;
180
181 if (off->vbase_descr >= 0)
182 {
183 int *offset_ptr;
184
185 /* move this ptr to vbase descriptor */
186 object = (char *)object + off->vbase_descr;
187 /* and fetch additional offset from vbase descriptor */
188 offset_ptr = (int *)(*(char **)object + off->vbase_offset);
189 object = (char *)object + *offset_ptr;
190 }
191
192 object = (char *)object + off->this_offset;
193 return object;
194}
195
196#ifdef __ASM_USE_THISCALL_WRAPPER
197extern void call_copy_ctor( void *func, void *this, void *src, int has_vbase );
198extern void call_dtor( void *func, void *this );
199#else
200static inline void call_copy_ctor( void *func, void *this, void *src, int has_vbase )
201{
202 if (has_vbase)
203 ((void (__thiscall*)(void*, void*, BOOL))func)(this, src, 1);
204 else
205 ((void (__thiscall*)(void*, void*))func)(this, src);
206}
207static inline void call_dtor( void *func, void *this )
208{
209 ((void (__thiscall*)(void*))func)( this );
210}
211#endif
212
213/* check if the exception type is caught by a given catch block, and return the type that matched */
215 const type_info *catch_ti, UINT catch_flags )
216{
217 const cxx_type_info_table *type_info_table = rtti_rva( exc_type->type_info_table, base );
218 UINT i;
219
220 for (i = 0; i < type_info_table->count; i++)
221 {
222 const cxx_type_info *type = rtti_rva( type_info_table->info[i], base );
223 const type_info *ti = rtti_rva( type->type_info, base );
224
225 if (!catch_ti) return type; /* catch(...) matches any type */
226 if (catch_ti != ti)
227 {
228 if (strcmp( catch_ti->mangled, ti->mangled )) continue;
229 }
230 /* type is the same, now check the flags */
231 if ((exc_type->flags & TYPE_FLAG_CONST) &&
232 !(catch_flags & TYPE_FLAG_CONST)) continue;
233 if ((exc_type->flags & TYPE_FLAG_VOLATILE) &&
234 !(catch_flags & TYPE_FLAG_VOLATILE)) continue;
235 return type; /* it matched */
236 }
237 return NULL;
238}
239
240/* copy the exception object where the catch block wants it */
241static inline void copy_exception( void *object, void **dest, UINT catch_flags,
243{
244 if (catch_flags & TYPE_FLAG_REFERENCE)
245 {
246 *dest = get_this_pointer( &type->offsets, object );
247 }
248 else if (type->flags & CLASS_IS_SIMPLE_TYPE)
249 {
250 memmove( dest, object, type->size );
251 /* if it is a pointer, adjust it */
252 if (type->size == sizeof(void*)) *dest = get_this_pointer( &type->offsets, *dest );
253 }
254 else /* copy the object */
255 {
256 if (type->copy_ctor)
257 call_copy_ctor( rtti_rva( type->copy_ctor, base ), dest,
258 get_this_pointer( &type->offsets, object ),
260 else
261 memmove( dest, get_this_pointer( &type->offsets, object ), type->size );
262 }
263}
264
265#define TRACE_EXCEPTION_TYPE(type,base) do { \
266 const cxx_type_info_table *table = rtti_rva( type->type_info_table, base ); \
267 unsigned int i; \
268 TRACE( "flags %x destr %p handler %p type info %p\n", \
269 type->flags, rtti_rva( type->destructor, base ), \
270 type->custom_handler ? rtti_rva( type->custom_handler, base ) : NULL, table ); \
271 for (i = 0; i < table->count; i++) \
272 { \
273 const cxx_type_info *type = rtti_rva( table->info[i], base ); \
274 const type_info *info = rtti_rva( type->type_info, base ); \
275 TRACE( " %d: flags %x type %p %s offsets %d,%d,%d size %d copy ctor %p\n", \
276 i, type->flags, info, dbgstr_type_info( info ), \
277 type->offsets.this_offset, type->offsets.vbase_descr, type->offsets.vbase_offset, \
278 type->size, rtti_rva( type->copy_ctor, base )); \
279 } \
280} while(0)
281
283extern void *find_catch_handler( void *object, uintptr_t frame, uintptr_t exc_base,
284 const tryblock_info *tryblock,
287 int (__cdecl *handler)(_FPIEEE_RECORD*) );
288#ifndef __i386__
292#endif
293
294#if _MSVCR_VER >= 80
295#define EXCEPTION_MANGLED_NAME ".?AVexception@std@@"
296#else
297#define EXCEPTION_MANGLED_NAME ".?AVexception@@"
298#endif
299
300#define CREATE_EXCEPTION_OBJECT(exception_name) \
301static exception* __exception_ctor(exception *this, const char *str, const vtable_ptr *vtbl) \
302{ \
303 if (str) \
304 { \
305 unsigned int len = strlen(str) + 1; \
306 this->name = malloc(len); \
307 memcpy(this->name, str, len); \
308 this->do_free = TRUE; \
309 } \
310 else \
311 { \
312 this->name = NULL; \
313 this->do_free = FALSE; \
314 } \
315 this->vtable = vtbl; \
316 return this; \
317} \
318\
319static exception* __exception_copy_ctor(exception *this, const exception *rhs, const vtable_ptr *vtbl) \
320{ \
321 if (rhs->do_free) \
322 { \
323 __exception_ctor(this, rhs->name, vtbl); \
324 } \
325 else \
326 { \
327 *this = *rhs; \
328 this->vtable = vtbl; \
329 } \
330 return this; \
331} \
332extern const vtable_ptr exception_name ## _vtable; \
333DEFINE_THISCALL_WRAPPER(exception_name ## _copy_ctor,8) \
334exception* __thiscall exception_name ## _copy_ctor(exception *this, const exception *rhs) \
335{ \
336 return __exception_copy_ctor(this, rhs, & exception_name ## _vtable); \
337} \
338\
339DEFINE_THISCALL_WRAPPER(exception_name ## _dtor,4) \
340void __thiscall exception_name ## _dtor(exception *this) \
341{ \
342 if (this->do_free) free(this->name); \
343} \
344\
345DEFINE_THISCALL_WRAPPER(exception_name ## _vector_dtor,8) \
346void* __thiscall exception_name ## _vector_dtor(exception *this, unsigned int flags) \
347{ \
348 if (flags & 2) \
349 { \
350 INT_PTR i, *ptr = (INT_PTR *)this - 1; \
351\
352 for (i = *ptr - 1; i >= 0; i--) exception_name ## _dtor(this + i); \
353 operator_delete(ptr); \
354 } \
355 else \
356 { \
357 exception_name ## _dtor(this); \
358 if (flags & 1) operator_delete(this); \
359 } \
360 return this; \
361} \
362\
363DEFINE_THISCALL_WRAPPER(exception_name ## _what,4) \
364const char* __thiscall exception_name ## _what(exception *this) \
365{ \
366 return this->name ? this->name : "Unknown exception"; \
367} \
368\
369__ASM_BLOCK_BEGIN(exception_name ## _vtables) \
370__ASM_VTABLE(exception_name, \
371 VTABLE_ADD_FUNC(exception_name ## _vector_dtor) \
372 VTABLE_ADD_FUNC(exception_name ## _what)); \
373__ASM_BLOCK_END \
374\
375DEFINE_RTTI_DATA0(exception_name, 0, EXCEPTION_MANGLED_NAME)
376
377#endif /* __MSVCRT_CPPEXCEPT_H */
void dispatch(HANDLE hStopEvent)
Definition: dispatch.c:70
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
const char * wine_dbg_sprintf(const char *format,...)
Definition: compat.c:296
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7512
DECLSPEC_NORETURN void WINAPI _CxxThrowException(void *, const cxx_exception_type *)
Definition: cpp.c:890
#define CXX_EXCEPTION
Definition: cppexcept.h:34
static const char * dbgstr_type_info(const type_info *info)
Definition: cppexcept.h:169
static const cxx_type_info * find_caught_type(cxx_exception_type *exc_type, uintptr_t base, const type_info *catch_ti, UINT catch_flags)
Definition: cppexcept.h:214
void __cdecl __ExceptionPtrCreate(exception_ptr *)
#define CLASS_IS_SIMPLE_TYPE
Definition: cppexcept.h:137
void throw_exception(const char *)
Definition: cpp.c:606
static void call_dtor(void *func, void *this)
Definition: cppexcept.h:207
#define CXX_FRAME_MAGIC_VC6
Definition: cppexcept.h:31
#define CLASS_HAS_VIRTUAL_BASE_CLASS
Definition: cppexcept.h:138
static void call_copy_ctor(void *func, void *this, void *src, int has_vbase)
Definition: cppexcept.h:200
#define CXX_FRAME_MAGIC_VC8
Definition: cppexcept.h:33
void exception_ptr_from_record(exception_ptr *, EXCEPTION_RECORD *)
static BOOL is_cxx_exception(EXCEPTION_RECORD *rec)
Definition: cppexcept.h:146
void dump_function_descr(const cxx_function_descr *descr, uintptr_t base)
Definition: except.c:50
BOOL __cdecl __uncaught_exception(void)
Definition: except.c:821
static void copy_exception(void *object, void **dest, UINT catch_flags, const cxx_type_info *type, uintptr_t base)
Definition: cppexcept.h:241
void * call_unwind_handler(void *func, uintptr_t frame, DISPATCHER_CONTEXT *dispatch)
int handle_fpieee_flt(__msvcrt_ulong exception_code, EXCEPTION_POINTERS *ep, int(__cdecl *handler)(_FPIEEE_RECORD *))
#define TYPE_FLAG_CONST
Definition: cppexcept.h:140
void __cdecl __ExceptionPtrDestroy(exception_ptr *)
void __cdecl __ExceptionPtrRethrow(const exception_ptr *)
Definition: cpp.c:1245
void * call_catch_handler(EXCEPTION_RECORD *rec)
#define CXX_EXCEPTION_PARAMS
Definition: cppexcept.h:89
#define TYPE_FLAG_VOLATILE
Definition: cppexcept.h:141
ULONG_PTR get_exception_pc(DISPATCHER_CONTEXT *dispatch)
void * find_catch_handler(void *object, uintptr_t frame, uintptr_t exc_base, const tryblock_info *tryblock, cxx_exception_type *exc_type, uintptr_t image_base)
Definition: except.c:96
static void * get_this_pointer(const this_ptr_offsets *off, void *object)
Definition: cppexcept.h:177
#define TYPE_FLAG_REFERENCE
Definition: cppexcept.h:142
struct __type_info type_info
static void * rtti_rva(unsigned int rva, uintptr_t base)
Definition: cxx.h:469
#define __cdecl
Definition: corecrt.h:121
unsigned int uintptr_t
Definition: corecrt.h:185
#define DECLSPEC_NORETURN
Definition: corecrt.h:131
unsigned long __msvcrt_ulong
Definition: corecrt.h:168
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
static void * image_base(void)
Definition: dll_register.c:28
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLenum func
Definition: glext.h:6028
GLenum src
Definition: glext.h:6340
GLintptr offset
Definition: glext.h:5920
GLbitfield flags
Definition: glext.h:7161
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define exception_code
Definition: excpt.h:84
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define __thiscall
Definition: cpp.c:43
static char * dest
Definition: rtl.c:135
unsigned int UINT
Definition: ndis.h:50
#define BOOL
Definition: nt_native.h:43
long LONG
Definition: pedump.c:60
const char * descr
Definition: boot.c:45
DWORD ExceptionCode
Definition: compat.h:208
DWORD NumberParameters
Definition: compat.h:212
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
char mangled[128]
Definition: cxx.h:335
unsigned int type_info_table
Definition: cxx.h:454
unsigned int info[5]
Definition: cxx.h:446
LONG * ref
Definition: cppexcept.h:157
EXCEPTION_RECORD * rec
Definition: cppexcept.h:156
int state
Definition: cppexcept.h:39
UINT ip
Definition: cppexcept.h:38
int this_offset
Definition: cxx.h:341
int vbase_offset
Definition: cxx.h:343
int vbase_descr
Definition: cxx.h:342
UINT catchblock_count
Definition: cppexcept.h:107
UINT catchblock
Definition: cppexcept.h:108
UINT handler
Definition: cppexcept.h:114
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define WINAPI
Definition: msvc.h:6