Changeset 10005 for trunk/src/msvcrt/cppexcept.c
- Timestamp:
- Apr 10, 2003, 12:28:07 PM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/msvcrt/cppexcept.c
r9633 r10005 25 25 #ifdef __WIN32OS2__ 26 26 #include <emxheader.h> 27 #include <string.h> 27 28 #include "winbase.h" 28 29 #else … … 38 39 #include "wine/debug.h" 39 40 41 #include "cppexcept.h" 42 40 43 WINE_DEFAULT_DEBUG_CHANNEL(seh); 41 42 #define CXX_FRAME_MAGIC 0x1993052043 #define CXX_EXCEPTION 0xe06d736344 45 typedef struct __type_info46 {47 void *vtable;48 void *data;49 char name[1];50 } type_info;51 52 /* the exception frame used by CxxFrameHandler */53 typedef struct __cxx_exception_frame54 {55 EXCEPTION_FRAME frame; /* the standard exception frame */56 int trylevel;57 DWORD ebp;58 } cxx_exception_frame;59 60 /* info about a single catch {} block */61 typedef struct __catchblock_info62 {63 UINT flags; /* flags (see below) */64 type_info *type_info; /* C++ type caught by this block */65 int offset; /* stack offset to copy exception object to */66 void (*handler)(); /* catch block handler code */67 } catchblock_info;68 #define TYPE_FLAG_CONST 169 #define TYPE_FLAG_VOLATILE 270 #define TYPE_FLAG_REFERENCE 871 72 /* info about a single try {} block */73 typedef struct __tryblock_info74 {75 int start_level; /* start trylevel of that block */76 int end_level; /* end trylevel of that block */77 int catch_level; /* initial trylevel of the catch block */78 int catchblock_count; /* count of catch blocks in array */79 catchblock_info *catchblock; /* array of catch blocks */80 } tryblock_info;81 82 /* info about the unwind handler for a given trylevel */83 typedef struct __unwind_info84 {85 int prev; /* prev trylevel unwind handler, to run after this one */86 void (*handler)(); /* unwind handler */87 } unwind_info;88 89 /* descriptor of all try blocks of a given function */90 typedef struct __cxx_function_descr91 {92 UINT magic; /* must be CXX_FRAME_MAGIC */93 UINT unwind_count; /* number of unwind handlers */94 unwind_info *unwind_table; /* array of unwind handlers */95 UINT tryblock_count; /* number of try blocks */96 tryblock_info *tryblock; /* array of try blocks */97 UINT unknown[3];98 } cxx_function_descr;99 100 /* complete information about a C++ type */101 typedef struct __cxx_type_info102 {103 UINT flags; /* flags (see CLASS_* flags below) */104 type_info *type_info; /* C++ type info */105 int this_offset; /* offset of base class this pointer from start of object */106 int vbase_descr; /* offset of virtual base class descriptor */107 int vbase_offset; /* offset of this pointer offset in virtual base class descriptor */108 size_t size; /* object size */109 void (*copy_ctor)(); /* copy constructor */110 } cxx_type_info;111 #define CLASS_IS_SIMPLE_TYPE 1112 #define CLASS_HAS_VIRTUAL_BASE_CLASS 4113 114 /* table of C++ types that apply for a given object */115 typedef struct __cxx_type_info_table116 {117 UINT count; /* number of types */118 cxx_type_info *info[1]; /* array of types */119 } cxx_type_info_table;120 121 typedef DWORD (*cxx_exc_custom_handler)( PEXCEPTION_RECORD, cxx_exception_frame*,122 PCONTEXT, struct __EXCEPTION_FRAME**,123 cxx_function_descr*, int nested_trylevel,124 EXCEPTION_FRAME *nested_frame, DWORD unknown3 );125 126 /* type information for an exception object */127 typedef struct __cxx_exception_type128 {129 UINT flags; /* TYPE_FLAG flags */130 void (*destructor)(); /* exception object destructor */131 cxx_exc_custom_handler custom_handler; /* custom handler for this exception */132 cxx_type_info_table *type_info_table; /* list of types for this exception object */133 } cxx_exception_type;134 135 44 136 45 #ifdef __i386__ /* CxxFrameHandler is not supported on non-i386 */ … … 170 79 171 80 172 static void dump_type( c xx_type_info *type )81 static void dump_type( const cxx_type_info *type ) 173 82 { 174 83 DPRINTF( "flags %x type %p", type->flags, type->type_info ); 175 if (type->type_info) DPRINTF( " (%p %s)", type->type_info-> data, type->type_info->name);84 if (type->type_info) DPRINTF( " (%p %s)", type->type_info->name, type->type_info->mangled ); 176 85 DPRINTF( " offset %d vbase %d,%d size %d copy ctor %p\n", type->this_offset, 177 86 type->vbase_descr, type->vbase_offset, type->size, type->copy_ctor ); 178 87 } 179 88 180 static void dump_exception_type( c xx_exception_type *type )181 { 182 inti;89 static void dump_exception_type( const cxx_exception_type *type ) 90 { 91 UINT i; 183 92 184 93 DPRINTF( "exception type:\n" ); … … 192 101 } 193 102 194 static void dump_function_descr( cxx_function_descr *descr, cxx_exception_type *info ) 195 { 196 int i, j; 103 static void dump_function_descr( const cxx_function_descr *descr, const cxx_exception_type *info ) 104 { 105 UINT i; 106 int j; 197 107 198 108 DPRINTF( "function descr:\n" ); … … 216 126 DPRINTF( " %d: flags %x offset %d handler %p type %p", 217 127 j, ptr->flags, ptr->offset, ptr->handler, ptr->type_info ); 218 if (ptr->type_info) DPRINTF( " (%p %s)", ptr->type_info-> data, ptr->type_info->name);128 if (ptr->type_info) DPRINTF( " (%p %s)", ptr->type_info->name, ptr->type_info->mangled ); 219 129 DPRINTF( "\n" ); 220 130 } … … 223 133 224 134 /* compute the this pointer for a base class of a given type */ 225 static void *get_this_pointer( c xx_type_info *type, void *object )135 static void *get_this_pointer( const cxx_type_info *type, void *object ) 226 136 { 227 137 void *this_ptr; … … 242 152 243 153 /* check if the exception type is caught by a given catch block, and return the type that matched */ 244 static c xx_type_info *find_caught_type( cxx_exception_type *exc_type, catchblock_info *catchblock )154 static const cxx_type_info *find_caught_type( cxx_exception_type *exc_type, catchblock_info *catchblock ) 245 155 { 246 156 UINT i; … … 248 158 for (i = 0; i < exc_type->type_info_table->count; i++) 249 159 { 250 c xx_type_info *type = exc_type->type_info_table->info[i];160 const cxx_type_info *type = exc_type->type_info_table->info[i]; 251 161 252 162 if (!catchblock->type_info) return type; /* catch(...) matches any type */ 253 163 if (catchblock->type_info != type->type_info) 254 164 { 255 if (strcmp( catchblock->type_info-> name, type->type_info->name)) continue;165 if (strcmp( catchblock->type_info->mangled, type->type_info->mangled )) continue; 256 166 } 257 167 /* type is the same, now check the flags */ … … 268 178 /* copy the exception object where the catch block wants it */ 269 179 static void copy_exception( void *object, cxx_exception_frame *frame, 270 catchblock_info *catchblock, c xx_type_info *type )180 catchblock_info *catchblock, const cxx_type_info *type ) 271 181 { 272 182 void **dest_ptr; 273 183 274 if (!catchblock->type_info || !catchblock->type_info-> name[0]) return;184 if (!catchblock->type_info || !catchblock->type_info->mangled[0]) return; 275 185 if (!catchblock->offset) return; 276 186 dest_ptr = (void **)((char *)&frame->ebp + catchblock->offset); … … 357 267 cxx_exception_type *info ) 358 268 { 359 int i, j; 269 UINT i; 270 int j; 360 271 void *addr, *object = (void *)rec->ExceptionInformation[1]; 361 272 struct catch_func_nested_frame nested_frame; … … 374 285 { 375 286 catchblock_info *catchblock = &tryblock->catchblock[j]; 376 c xx_type_info *type = find_caught_type( info, catchblock );287 const cxx_type_info *type = find_caught_type( info, catchblock ); 377 288 if (!type) continue; 378 289 … … 497 408 * _CxxThrowException (MSVCRT.@) 498 409 */ 499 void _CxxThrowException( void *object, c xx_exception_type *type )410 void _CxxThrowException( void *object, const cxx_exception_type *type ) 500 411 { 501 412 DWORD args[3]; … … 506 417 RaiseException( CXX_EXCEPTION, EH_NONCONTINUABLE, 3, args ); 507 418 } 419 420 /********************************************************************* 421 * __CxxDetectRethrow (MSVCRT.@) 422 */ 423 BOOL __CxxDetectRethrow(PEXCEPTION_POINTERS ptrs) 424 { 425 PEXCEPTION_RECORD rec; 426 427 if (!ptrs) 428 return FALSE; 429 430 rec = ptrs->ExceptionRecord; 431 432 if (rec->ExceptionCode == CXX_EXCEPTION && 433 rec->NumberParameters == 3 && 434 rec->ExceptionInformation[0] == CXX_FRAME_MAGIC && 435 rec->ExceptionInformation[2]) 436 { 437 ptrs->ExceptionRecord = msvcrt_get_thread_data()->exc_record; 438 return TRUE; 439 } 440 return (msvcrt_get_thread_data()->exc_record == rec); 441 } 442 443 /********************************************************************* 444 * __CxxQueryExceptionSize (MSVCRT.@) 445 */ 446 unsigned int __CxxQueryExceptionSize(void) 447 { 448 return sizeof(cxx_exception_type); 449 }
Note:
See TracChangeset
for help on using the changeset viewer.