msvcp140: Import __ExceptionPtrCompare implementation.
[wine.git] / dlls / msvcp90 / exception.c
blob8ceaa91e884d0fce0763d6d536965b1446e6d162
1 /*
2 * Copyright 2010 Piotr Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <stdarg.h>
21 #include "msvcp90.h"
22 #include "windef.h"
23 #include "winbase.h"
24 #include "winternl.h"
25 #include "wine/debug.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(msvcp);
29 #define CXX_FRAME_MAGIC_VC6 0x19930520
31 CREATE_TYPE_INFO_VTABLE
33 #define CLASS_IS_SIMPLE_TYPE 1
34 #define CLASS_HAS_VIRTUAL_BASE_CLASS 4
36 int* __cdecl __processing_throw(void);
38 #if _MSVCP_VER >= 70 || defined(_MSVCIRT)
39 typedef const char **exception_name;
40 #define EXCEPTION_STR(name) (*name)
41 #define EXCEPTION_NAME(str) (&str)
42 #else
43 typedef const char *exception_name;
44 #define EXCEPTION_STR(name) (name)
45 #define EXCEPTION_NAME(str) (str)
46 #endif
48 void (CDECL *_Raise_handler)(const exception*) = NULL;
50 /* vtables */
51 extern const vtable_ptr exception_vtable;
52 /* ??_7bad_alloc@std@@6B@ */
53 extern const vtable_ptr bad_alloc_vtable;
54 /* ??_7logic_error@std@@6B@ */
55 extern const vtable_ptr logic_error_vtable;
56 /* ??_7length_error@std@@6B@ */
57 extern const vtable_ptr length_error_vtable;
58 /* ??_7out_of_range@std@@6B@ */
59 extern const vtable_ptr out_of_range_vtable;
60 extern const vtable_ptr invalid_argument_vtable;
61 /* ??_7runtime_error@std@@6B@ */
62 extern const vtable_ptr runtime_error_vtable;
63 extern const vtable_ptr _System_error_vtable;
64 extern const vtable_ptr system_error_vtable;
65 extern const vtable_ptr failure_vtable;
66 /* ??_7bad_cast@std@@6B@ */
67 extern const vtable_ptr bad_cast_vtable;
68 /* ??_7range_error@std@@6B@ */
69 extern const vtable_ptr range_error_vtable;
71 /* ??0exception@@QAE@ABQBD@Z */
72 /* ??0exception@@QEAA@AEBQEBD@Z */
73 DEFINE_THISCALL_WRAPPER(MSVCP_exception_ctor,8)
74 exception* __thiscall MSVCP_exception_ctor(exception *this, exception_name name)
76 TRACE("(%p %s)\n", this, EXCEPTION_STR(name));
78 this->vtable = &exception_vtable;
79 if(EXCEPTION_STR(name)) {
80 unsigned int name_len = strlen(EXCEPTION_STR(name)) + 1;
81 this->name = malloc(name_len);
82 memcpy(this->name, EXCEPTION_STR(name), name_len);
83 this->do_free = TRUE;
84 } else {
85 this->name = NULL;
86 this->do_free = FALSE;
88 return this;
91 DEFINE_THISCALL_WRAPPER(exception_copy_ctor,8)
92 exception* __thiscall exception_copy_ctor(exception *this, const exception *rhs)
94 TRACE("(%p,%p)\n", this, rhs);
96 if(!rhs->do_free) {
97 this->vtable = &exception_vtable;
98 this->name = rhs->name;
99 this->do_free = FALSE;
100 } else
101 MSVCP_exception_ctor(this, (exception_name)EXCEPTION_NAME(rhs->name));
102 TRACE("name = %s\n", this->name);
103 return this;
106 /* ??0exception@@QAE@XZ */
107 /* ??0exception@@QEAA@XZ */
108 DEFINE_THISCALL_WRAPPER(MSVCP_exception_default_ctor,4)
109 exception* __thiscall MSVCP_exception_default_ctor(exception *this)
111 TRACE("(%p)\n", this);
112 this->vtable = &exception_vtable;
113 this->name = NULL;
114 this->do_free = FALSE;
115 return this;
118 DEFINE_THISCALL_WRAPPER(MSVCP_exception_dtor,4)
119 void __thiscall MSVCP_exception_dtor(exception *this)
121 TRACE("(%p)\n", this);
122 this->vtable = &exception_vtable;
123 if(this->do_free)
124 free(this->name);
127 DEFINE_THISCALL_WRAPPER(MSVCP_exception_vector_dtor, 8)
128 void * __thiscall MSVCP_exception_vector_dtor(exception *this, unsigned int flags)
130 TRACE("%p %x\n", this, flags);
131 if(flags & 2) {
132 /* we have an array, with the number of elements stored before the first object */
133 INT_PTR i, *ptr = (INT_PTR *)this-1;
135 for(i=*ptr-1; i>=0; i--)
136 MSVCP_exception_dtor(this+i);
137 operator_delete(ptr);
138 } else {
139 MSVCP_exception_dtor(this);
140 if(flags & 1)
141 operator_delete(this);
144 return this;
147 /* ??_Gexception@@UAEPAXI@Z */
148 DEFINE_THISCALL_WRAPPER(MSVCP_exception_scalar_dtor, 8)
149 void * __thiscall MSVCP_exception_scalar_dtor(exception *this, unsigned int flags)
151 TRACE("(%p %x)\n", this, flags);
152 MSVCP_exception_dtor(this);
153 if (flags & 1) operator_delete(this);
154 return this;
157 /* ??4exception@@QAEAAV0@ABV0@@Z */
158 /* ??4exception@@QEAAAEAV0@AEBV0@@Z */
159 DEFINE_THISCALL_WRAPPER(MSVCP_exception_assign, 8)
160 exception* __thiscall MSVCP_exception_assign(exception *this, const exception *assign)
162 MSVCP_exception_dtor(this);
163 return exception_copy_ctor(this, assign);
166 /* ?_Doraise@bad_alloc@std@@MBEXXZ */
167 /* ?_Doraise@bad_alloc@std@@MEBAXXZ */
168 /* ?_Doraise@logic_error@std@@MBEXXZ */
169 /* ?_Doraise@logic_error@std@@MEBAXXZ */
170 /* ?_Doraise@length_error@std@@MBEXXZ */
171 /* ?_Doraise@length_error@std@@MEBAXXZ */
172 /* ?_Doraise@out_of_range@std@@MBEXXZ */
173 /* ?_Doraise@out_of_range@std@@MEBAXXZ */
174 /* ?_Doraise@runtime_error@std@@MBEXXZ */
175 /* ?_Doraise@runtime_error@std@@MEBAXXZ */
176 /* ?_Doraise@bad_cast@std@@MBEXXZ */
177 /* ?_Doraise@bad_cast@std@@MEBAXXZ */
178 /* ?_Doraise@range_error@std@@MBEXXZ */
179 /* ?_Doraise@range_error@std@@MEBAXXZ */
180 DEFINE_THISCALL_WRAPPER(MSVCP_exception__Doraise, 4)
181 void __thiscall MSVCP_exception__Doraise(exception *this)
183 FIXME("(%p) stub\n", this);
186 DEFINE_THISCALL_WRAPPER(MSVCP_exception_what,4)
187 const char* __thiscall MSVCP_exception_what(exception * this)
189 TRACE("(%p) returning %s\n", this, this->name);
190 return this->name ? this->name : "Unknown exception";
193 #if _MSVCP_VER >= 80
194 DEFINE_RTTI_DATA0(exception, 0, ".?AVexception@std@@")
195 #else
196 DEFINE_RTTI_DATA0(exception, 0, ".?AVexception@@")
197 #endif
198 DEFINE_CXX_DATA0(exception, MSVCP_exception_dtor)
200 /* bad_alloc class data */
201 typedef exception bad_alloc;
203 /* ??0bad_alloc@std@@QAE@PBD@Z */
204 /* ??0bad_alloc@std@@QEAA@PEBD@Z */
205 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_ctor, 8)
206 bad_alloc* __thiscall MSVCP_bad_alloc_ctor(bad_alloc *this, exception_name name)
208 TRACE("%p %s\n", this, EXCEPTION_STR(name));
209 MSVCP_exception_ctor(this, name);
210 this->vtable = &bad_alloc_vtable;
211 return this;
214 /* ??0bad_alloc@std@@QAE@XZ */
215 /* ??0bad_alloc@std@@QEAA@XZ */
216 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_default_ctor, 4)
217 bad_alloc* __thiscall MSVCP_bad_alloc_default_ctor(bad_alloc *this)
219 static const char *name = "bad allocation";
220 return MSVCP_bad_alloc_ctor(this, EXCEPTION_NAME(name));
223 /* ??0bad_alloc@std@@QAE@ABV01@@Z */
224 /* ??0bad_alloc@std@@QEAA@AEBV01@@Z */
225 DEFINE_THISCALL_WRAPPER(bad_alloc_copy_ctor, 8)
226 bad_alloc* __thiscall bad_alloc_copy_ctor(bad_alloc *this, const bad_alloc *rhs)
228 TRACE("%p %p\n", this, rhs);
229 exception_copy_ctor(this, rhs);
230 this->vtable = &bad_alloc_vtable;
231 return this;
234 /* ??1bad_alloc@std@@UAE@XZ */
235 /* ??1bad_alloc@std@@UEAA@XZ */
236 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_dtor, 4)
237 void __thiscall MSVCP_bad_alloc_dtor(bad_alloc *this)
239 TRACE("%p\n", this);
240 MSVCP_exception_dtor(this);
243 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_vector_dtor, 8)
244 void * __thiscall MSVCP_bad_alloc_vector_dtor(bad_alloc *this, unsigned int flags)
246 TRACE("%p %x\n", this, flags);
247 if(flags & 2) {
248 /* we have an array, with the number of elements stored before the first object */
249 INT_PTR i, *ptr = (INT_PTR *)this-1;
251 for(i=*ptr-1; i>=0; i--)
252 MSVCP_bad_alloc_dtor(this+i);
253 operator_delete(ptr);
254 } else {
255 MSVCP_bad_alloc_dtor(this);
256 if(flags & 1)
257 operator_delete(this);
260 return this;
263 /* ??4bad_alloc@std@@QAEAAV01@ABV01@@Z */
264 /* ??4bad_alloc@std@@QEAAAEAV01@AEBV01@@Z */
265 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_assign, 8)
266 bad_alloc* __thiscall MSVCP_bad_alloc_assign(bad_alloc *this, const bad_alloc *assign)
268 MSVCP_bad_alloc_dtor(this);
269 return bad_alloc_copy_ctor(this, assign);
272 DEFINE_RTTI_DATA1(bad_alloc, 0, &exception_rtti_base_descriptor, ".?AVbad_alloc@std@@")
273 DEFINE_CXX_DATA1(bad_alloc, &exception_cxx_type_info, MSVCP_bad_alloc_dtor)
275 /* logic_error class data */
276 typedef struct {
277 exception e;
278 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
279 basic_string_char str;
280 #endif
281 } logic_error;
283 /* ??0logic_error@@QAE@ABQBD@Z */
284 /* ??0logic_error@@QEAA@AEBQEBD@Z */
285 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_ctor, 8)
286 logic_error* __thiscall MSVCP_logic_error_ctor( logic_error *this, exception_name name )
288 TRACE("%p %s\n", this, EXCEPTION_STR(name));
289 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
290 #if _MSVCP_VER == 60
291 MSVCP_exception_ctor(&this->e, "");
292 #else
293 MSVCP_exception_default_ctor(&this->e);
294 #endif
295 MSVCP_basic_string_char_ctor_cstr(&this->str, EXCEPTION_STR(name));
296 #else
297 MSVCP_exception_ctor(&this->e, name);
298 #endif
299 this->e.vtable = &logic_error_vtable;
300 return this;
303 /* ??0logic_error@std@@QAE@ABV01@@Z */
304 /* ??0logic_error@std@@QEAA@AEBV01@@Z */
305 DEFINE_THISCALL_WRAPPER(logic_error_copy_ctor, 8)
306 logic_error* __thiscall logic_error_copy_ctor(
307 logic_error *this, const logic_error *rhs)
309 TRACE("%p %p\n", this, rhs);
310 exception_copy_ctor(&this->e, &rhs->e);
311 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
312 MSVCP_basic_string_char_copy_ctor(&this->str, &rhs->str);
313 #endif
314 this->e.vtable = &logic_error_vtable;
315 return this;
318 /* ??0logic_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
319 /* ??0logic_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
320 #ifndef _MSVCIRT
321 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_ctor_bstr, 8)
322 logic_error* __thiscall MSVCP_logic_error_ctor_bstr(logic_error *this, const basic_string_char *str)
324 const char *name = MSVCP_basic_string_char_c_str(str);
325 TRACE("(%p %p %s)\n", this, str, name);
326 return MSVCP_logic_error_ctor(this, EXCEPTION_NAME(name));
328 #endif
330 /* ??1logic_error@std@@UAE@XZ */
331 /* ??1logic_error@std@@UEAA@XZ */
332 /* ??1length_error@std@@UAE@XZ */
333 /* ??1length_error@std@@UEAA@XZ */
334 /* ??1out_of_range@std@@UAE@XZ */
335 /* ??1out_of_range@std@@UEAA@XZ */
336 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_dtor, 4)
337 void __thiscall MSVCP_logic_error_dtor(logic_error *this)
339 TRACE("%p\n", this);
340 MSVCP_exception_dtor(&this->e);
341 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
342 MSVCP_basic_string_char_dtor(&this->str);
343 #endif
346 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_vector_dtor, 8)
347 void* __thiscall MSVCP_logic_error_vector_dtor(
348 logic_error *this, unsigned int flags)
350 TRACE("%p %x\n", this, flags);
351 if(flags & 2) {
352 /* we have an array, with the number of elements stored before the first object */
353 INT_PTR i, *ptr = (INT_PTR *)this-1;
355 for(i=*ptr-1; i>=0; i--)
356 MSVCP_logic_error_dtor(this+i);
357 operator_delete(ptr);
358 } else {
359 MSVCP_logic_error_dtor(this);
360 if(flags & 1)
361 operator_delete(this);
364 return this;
367 /* ??_Glogic_error@@UAEPAXI@Z */
368 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_scalar_dtor, 8)
369 void * __thiscall MSVCP_logic_error_scalar_dtor(logic_error *this, unsigned int flags)
371 TRACE("(%p %x)\n", this, flags);
372 MSVCP_logic_error_dtor(this);
373 if (flags & 1) operator_delete(this);
374 return this;
377 /* ??4logic_error@std@@QAEAAV01@ABV01@@Z */
378 /* ??4logic_error@std@@QEAAAEAV01@AEBV01@@Z */
379 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_assign, 8)
380 logic_error* __thiscall MSVCP_logic_error_assign(logic_error *this, const logic_error *assign)
382 MSVCP_logic_error_dtor(this);
383 return logic_error_copy_ctor(this, assign);
386 /* ?what@logic_error@std@@UBEPBDXZ */
387 /* ?what@logic_error@std@@UEBAPEBDXZ */
388 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_what, 4)
389 const char* __thiscall MSVCP_logic_error_what(logic_error *this)
391 TRACE("%p\n", this);
392 #if _MSVCP_VER > 90 || defined _MSVCIRT
393 return MSVCP_exception_what( &this->e );
394 #else
395 return MSVCP_basic_string_char_c_str(&this->str);
396 #endif
399 #if _MSVCP_VER >= 80
400 DEFINE_RTTI_DATA1(logic_error, 0, &exception_rtti_base_descriptor, ".?AVlogic_error@std@@")
401 #else
402 DEFINE_RTTI_DATA1(logic_error, 0, &exception_rtti_base_descriptor, ".?AVlogic_error@@")
403 #endif
404 DEFINE_CXX_TYPE_INFO(logic_error)
406 /* length_error class data */
407 typedef logic_error length_error;
409 static length_error* MSVCP_length_error_ctor( length_error *this, exception_name name )
411 TRACE("%p %s\n", this, EXCEPTION_STR(name));
412 MSVCP_logic_error_ctor(this, name);
413 this->e.vtable = &length_error_vtable;
414 return this;
417 /* ??0length_error@std@@QAE@ABV01@@Z */
418 /* ??0length_error@std@@QEAA@AEBV01@@Z */
419 DEFINE_THISCALL_WRAPPER(length_error_copy_ctor, 8)
420 length_error* __thiscall length_error_copy_ctor(
421 length_error *this, const length_error *rhs)
423 TRACE("%p %p\n", this, rhs);
424 logic_error_copy_ctor(this, rhs);
425 this->e.vtable = &length_error_vtable;
426 return this;
429 /* ??0length_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
430 /* ??0length_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
431 #ifndef _MSVCIRT
432 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_ctor_bstr, 8)
433 length_error* __thiscall MSVCP_length_error_ctor_bstr(length_error *this, const basic_string_char *str)
435 const char *name = MSVCP_basic_string_char_c_str(str);
436 TRACE("(%p %p %s)\n", this, str, name);
437 return MSVCP_length_error_ctor(this, EXCEPTION_NAME(name));
439 #endif
441 /* ??4length_error@std@@QAEAAV01@ABV01@@Z */
442 /* ??4length_error@std@@QEAAAEAV01@AEBV01@@Z */
443 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_assign, 8)
444 length_error* __thiscall MSVCP_length_error_assign(length_error *this, const length_error *assign)
446 MSVCP_logic_error_dtor(this);
447 return length_error_copy_ctor(this, assign);
450 DEFINE_RTTI_DATA2(length_error, 0, &logic_error_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AVlength_error@std@@")
451 DEFINE_CXX_DATA2(length_error, &logic_error_cxx_type_info, &exception_cxx_type_info, MSVCP_logic_error_dtor)
453 /* out_of_range class data */
454 typedef logic_error out_of_range;
456 static out_of_range* MSVCP_out_of_range_ctor( out_of_range *this, exception_name name )
458 TRACE("%p %s\n", this, EXCEPTION_STR(name));
459 MSVCP_logic_error_ctor(this, name);
460 this->e.vtable = &out_of_range_vtable;
461 return this;
464 /* ??0out_of_range@std@@QAE@ABV01@@Z */
465 /* ??0out_of_range@std@@QEAA@AEBV01@@Z */
466 DEFINE_THISCALL_WRAPPER(out_of_range_copy_ctor, 8)
467 out_of_range* __thiscall out_of_range_copy_ctor(
468 out_of_range *this, const out_of_range *rhs)
470 TRACE("%p %p\n", this, rhs);
471 logic_error_copy_ctor(this, rhs);
472 this->e.vtable = &out_of_range_vtable;
473 return this;
476 /* ??0out_of_range@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
477 /* ??0out_of_range@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
478 #ifndef _MSVCIRT
479 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_ctor_bstr, 8)
480 out_of_range* __thiscall MSVCP_out_of_range_ctor_bstr(out_of_range *this, const basic_string_char *str)
482 const char *name = MSVCP_basic_string_char_c_str(str);
483 TRACE("(%p %p %s)\n", this, str, name);
484 return MSVCP_out_of_range_ctor(this, EXCEPTION_NAME(name));
486 #endif
488 /* ??4out_of_range@std@@QAEAAV01@ABV01@@Z */
489 /* ??4out_of_range@std@@QEAAAEAV01@AEBV01@@Z */
490 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_assign, 8)
491 out_of_range* __thiscall MSVCP_out_of_range_assign(out_of_range *this, const out_of_range *assign)
493 MSVCP_logic_error_dtor(this);
494 return out_of_range_copy_ctor(this, assign);
497 DEFINE_RTTI_DATA2(out_of_range, 0, &logic_error_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AVout_of_range@std@@")
498 DEFINE_CXX_DATA2(out_of_range, &logic_error_cxx_type_info, &exception_cxx_type_info, MSVCP_logic_error_dtor)
500 /* invalid_argument class data */
501 typedef logic_error invalid_argument;
503 static invalid_argument* MSVCP_invalid_argument_ctor( invalid_argument *this, exception_name name )
505 TRACE("%p %s\n", this, EXCEPTION_STR(name));
506 MSVCP_logic_error_ctor(this, name);
507 this->e.vtable = &invalid_argument_vtable;
508 return this;
511 DEFINE_THISCALL_WRAPPER(invalid_argument_copy_ctor, 8)
512 invalid_argument* __thiscall invalid_argument_copy_ctor(
513 invalid_argument *this, invalid_argument *rhs)
515 TRACE("%p %p\n", this, rhs);
516 logic_error_copy_ctor(this, rhs);
517 this->e.vtable = &invalid_argument_vtable;
518 return this;
521 DEFINE_RTTI_DATA2(invalid_argument, 0, &logic_error_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AVinvalid_argument@std@@")
522 DEFINE_CXX_DATA2(invalid_argument, &logic_error_cxx_type_info, &exception_cxx_type_info, MSVCP_logic_error_dtor)
524 /* runtime_error class data */
525 typedef struct {
526 exception e;
527 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
528 basic_string_char str;
529 #endif
530 } runtime_error;
532 static runtime_error* MSVCP_runtime_error_ctor( runtime_error *this, exception_name name )
534 TRACE("%p %s\n", this, EXCEPTION_STR(name));
535 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
536 #if _MSVCP_VER == 60
537 MSVCP_exception_ctor(&this->e, "");
538 #else
539 MSVCP_exception_default_ctor(&this->e);
540 #endif
541 MSVCP_basic_string_char_ctor_cstr(&this->str, EXCEPTION_STR(name));
542 #else
543 MSVCP_exception_ctor(&this->e, name);
544 #endif
545 this->e.vtable = &runtime_error_vtable;
546 return this;
549 /* ??0runtime_error@std@@QAE@ABV01@@Z */
550 /* ??0runtime_error@std@@QEAA@AEBV01@@Z */
551 DEFINE_THISCALL_WRAPPER(runtime_error_copy_ctor, 8)
552 runtime_error* __thiscall runtime_error_copy_ctor(
553 runtime_error *this, const runtime_error *rhs)
555 TRACE("%p %p\n", this, rhs);
556 exception_copy_ctor(&this->e, &rhs->e);
557 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
558 MSVCP_basic_string_char_copy_ctor(&this->str, &rhs->str);
559 #endif
560 this->e.vtable = &runtime_error_vtable;
561 return this;
564 /* ??0runtime_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
565 /* ??0runtime_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
566 #ifndef _MSVCIRT
567 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_ctor_bstr, 8)
568 runtime_error* __thiscall MSVCP_runtime_error_ctor_bstr(runtime_error *this, const basic_string_char *str)
570 const char *name = MSVCP_basic_string_char_c_str(str);
571 TRACE("(%p %p %s)\n", this, str, name);
572 return MSVCP_runtime_error_ctor(this, EXCEPTION_NAME(name));
574 #endif
576 /* ??1runtime_error@std@@UAE@XZ */
577 /* ??1runtime_error@std@@UEAA@XZ */
578 /* ??1range_error@std@@UAE@XZ */
579 /* ??1range_error@std@@UEAA@XZ */
580 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_dtor, 4)
581 void __thiscall MSVCP_runtime_error_dtor(runtime_error *this)
583 TRACE("%p\n", this);
584 MSVCP_exception_dtor(&this->e);
585 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
586 MSVCP_basic_string_char_dtor(&this->str);
587 #endif
590 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_vector_dtor, 8)
591 void* __thiscall MSVCP_runtime_error_vector_dtor(
592 runtime_error *this, unsigned int flags)
594 TRACE("%p %x\n", this, flags);
595 if(flags & 2) {
596 /* we have an array, with the number of elements stored before the first object */
597 INT_PTR i, *ptr = (INT_PTR *)this-1;
599 for(i=*ptr-1; i>=0; i--)
600 MSVCP_runtime_error_dtor(this+i);
601 operator_delete(ptr);
602 } else {
603 MSVCP_runtime_error_dtor(this);
604 if(flags & 1)
605 operator_delete(this);
608 return this;
611 /* ??4runtime_error@std@@QAEAAV01@ABV01@@Z */
612 /* ??4runtime_error@std@@QEAAAEAV01@AEBV01@@Z */
613 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_assign, 8)
614 runtime_error* __thiscall MSVCP_runtime_error_assign(runtime_error *this, const runtime_error *assign)
616 MSVCP_runtime_error_dtor(this);
617 return runtime_error_copy_ctor(this, assign);
620 /* ?what@runtime_error@std@@UBEPBDXZ */
621 /* ?what@runtime_error@std@@UEBAPEBDXZ */
622 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_what, 4)
623 const char* __thiscall MSVCP_runtime_error_what(runtime_error *this)
625 TRACE("%p\n", this);
626 #if _MSVCP_VER > 90 || defined _MSVCIRT
627 return MSVCP_exception_what( &this->e );
628 #else
629 return MSVCP_basic_string_char_c_str(&this->str);
630 #endif
633 DEFINE_RTTI_DATA1(runtime_error, 0, &exception_rtti_base_descriptor, ".?AVruntime_error@std@@")
634 DEFINE_CXX_DATA1(runtime_error, &exception_cxx_type_info, MSVCP_runtime_error_dtor)
636 /* failure class data */
637 typedef struct {
638 runtime_error base;
639 #if _MSVCP_VER > 90
640 int err;
641 #endif
642 } system_error;
643 typedef system_error _System_error;
644 typedef system_error failure;
646 static failure* MSVCP_failure_ctor( failure *this, exception_name name )
648 TRACE("%p %s\n", this, EXCEPTION_STR(name));
649 MSVCP_runtime_error_ctor(&this->base, name);
650 #if _MSVCP_VER > 90
651 /* FIXME: set err correctly */
652 this->err = 0;
653 #endif
654 this->base.e.vtable = &failure_vtable;
655 return this;
658 DEFINE_THISCALL_WRAPPER(failure_copy_ctor, 8)
659 failure* __thiscall failure_copy_ctor(
660 failure *this, failure *rhs)
662 TRACE("%p %p\n", this, rhs);
663 runtime_error_copy_ctor(&this->base, &rhs->base);
664 #if _MSVCP_VER > 90
665 this->err = rhs->err;
666 #endif
667 this->base.e.vtable = &failure_vtable;
668 return this;
671 DEFINE_THISCALL_WRAPPER(MSVCP_failure_dtor, 4)
672 void __thiscall MSVCP_failure_dtor(failure *this)
674 TRACE("%p\n", this);
675 MSVCP_runtime_error_dtor(&this->base);
678 DEFINE_THISCALL_WRAPPER(MSVCP_failure_vector_dtor, 8)
679 void* __thiscall MSVCP_failure_vector_dtor(
680 failure *this, unsigned int flags)
682 TRACE("%p %x\n", this, flags);
683 return MSVCP_runtime_error_vector_dtor(&this->base, flags);
686 DEFINE_THISCALL_WRAPPER(MSVCP_failure_what, 4)
687 const char* __thiscall MSVCP_failure_what(failure *this)
689 TRACE("%p\n", this);
690 return MSVCP_runtime_error_what(&this->base);
693 #if _MSVCP_VER > 90
694 DEFINE_THISCALL_WRAPPER(system_error_copy_ctor, 8)
695 system_error* __thiscall system_error_copy_ctor(
696 system_error *this, system_error *rhs)
698 failure_copy_ctor(this, rhs);
699 this->base.e.vtable = &system_error_vtable;
700 return this;
702 #endif
704 #if _MSVCP_VER > 110
705 DEFINE_THISCALL_WRAPPER(_System_error_copy_ctor, 8)
706 _System_error* __thiscall _System_error_copy_ctor(
707 _System_error *this, _System_error *rhs)
709 failure_copy_ctor(this, rhs);
710 this->base.e.vtable = &_System_error_vtable;
711 return this;
713 #endif
715 #if _MSVCP_VER > 110
716 DEFINE_RTTI_DATA2(_System_error, 0, &runtime_error_rtti_base_descriptor,
717 &exception_rtti_base_descriptor, ".?AV_System_error@std@@")
718 DEFINE_RTTI_DATA3(system_error, 0, &_System_error_rtti_base_descriptor,
719 &runtime_error_rtti_base_descriptor, &exception_rtti_base_descriptor,
720 ".?AVsystem_error@std@@")
721 DEFINE_RTTI_DATA4(failure, 0, &system_error_rtti_base_descriptor,
722 &_System_error_rtti_base_descriptor, &runtime_error_rtti_base_descriptor,
723 &exception_rtti_base_descriptor, ".?AVfailure@ios_base@std@@")
724 DEFINE_CXX_TYPE_INFO(_System_error)
725 DEFINE_CXX_TYPE_INFO(system_error);
726 DEFINE_CXX_DATA4(failure, &system_error_cxx_type_info,
727 &_System_error_cxx_type_info, &runtime_error_cxx_type_info,
728 &exception_cxx_type_info, MSVCP_runtime_error_dtor)
729 #elif _MSVCP_VER > 90
730 DEFINE_RTTI_DATA2(system_error, 0, &runtime_error_rtti_base_descriptor,
731 &exception_rtti_base_descriptor, ".?AVsystem_error@std@@")
732 DEFINE_RTTI_DATA3(failure, 0, &system_error_rtti_base_descriptor,
733 &runtime_error_rtti_base_descriptor, &exception_rtti_base_descriptor,
734 ".?AVfailure@ios_base@std@@")
735 DEFINE_CXX_TYPE_INFO(system_error);
736 DEFINE_CXX_DATA3(failure, &system_error_cxx_type_info, &runtime_error_cxx_type_info,
737 &exception_cxx_type_info, MSVCP_runtime_error_dtor)
738 #else
739 DEFINE_RTTI_DATA2(failure, 0, &runtime_error_rtti_base_descriptor,
740 &exception_rtti_base_descriptor, ".?AVfailure@ios_base@std@@")
741 DEFINE_CXX_DATA2(failure, &runtime_error_cxx_type_info,
742 &exception_cxx_type_info, MSVCP_runtime_error_dtor)
743 #endif
745 /* bad_cast class data */
746 typedef exception bad_cast;
748 /* ??0bad_cast@std@@QAE@PBD@Z */
749 /* ??0bad_cast@std@@QEAA@PEBD@Z */
750 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_ctor, 8)
751 bad_cast* __thiscall MSVCP_bad_cast_ctor(bad_cast *this, const char *name)
753 TRACE("%p %s\n", this, name);
754 MSVCP_exception_ctor(this, EXCEPTION_NAME(name));
755 this->vtable = &bad_cast_vtable;
756 return this;
759 /* ??_Fbad_cast@@QAEXXZ */
760 /* ??_Fbad_cast@std@@QEAAXXZ */
761 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_default_ctor,4)
762 bad_cast* __thiscall MSVCP_bad_cast_default_ctor(bad_cast *this)
764 return MSVCP_bad_cast_ctor(this, "bad cast");
767 /* ??0bad_cast@std@@QAE@ABV01@@Z */
768 /* ??0bad_cast@std@@QEAA@AEBV01@@Z */
769 DEFINE_THISCALL_WRAPPER(bad_cast_copy_ctor, 8)
770 bad_cast* __thiscall bad_cast_copy_ctor(bad_cast *this, const bad_cast *rhs)
772 TRACE("%p %p\n", this, rhs);
773 exception_copy_ctor(this, rhs);
774 this->vtable = &bad_cast_vtable;
775 return this;
778 /* ??1bad_cast@@UAE@XZ */
779 /* ??1bad_cast@std@@UEAA@XZ */
780 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_dtor, 4)
781 void __thiscall MSVCP_bad_cast_dtor(bad_cast *this)
783 TRACE("%p\n", this);
784 MSVCP_exception_dtor(this);
787 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_vector_dtor, 8)
788 void * __thiscall MSVCP_bad_cast_vector_dtor(bad_cast *this, unsigned int flags)
790 TRACE("%p %x\n", this, flags);
791 if(flags & 2) {
792 /* we have an array, with the number of elements stored before the first object */
793 INT_PTR i, *ptr = (INT_PTR *)this-1;
795 for(i=*ptr-1; i>=0; i--)
796 MSVCP_bad_cast_dtor(this+i);
797 operator_delete(ptr);
798 } else {
799 MSVCP_bad_cast_dtor(this);
800 if(flags & 1)
801 operator_delete(this);
804 return this;
807 /* ??4bad_cast@std@@QAEAAV01@ABV01@@Z */
808 /* ??4bad_cast@std@@QEAAAEAV01@AEBV01@@Z */
809 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_opequals, 8)
810 bad_cast* __thiscall MSVCP_bad_cast_opequals(bad_cast *this, const bad_cast *rhs)
812 TRACE("(%p %p)\n", this, rhs);
814 if(this != rhs) {
815 MSVCP_exception_dtor(this);
816 exception_copy_ctor(this, rhs);
818 return this;
821 DEFINE_RTTI_DATA1(bad_cast, 0, &exception_rtti_base_descriptor, ".?AVbad_cast@std@@")
823 /* range_error class data */
824 typedef runtime_error range_error;
826 static range_error* MSVCP_range_error_ctor( range_error *this, exception_name name )
828 TRACE("%p %s\n", this, EXCEPTION_STR(name));
829 MSVCP_runtime_error_ctor(this, name);
830 this->e.vtable = &range_error_vtable;
831 return this;
834 /* ??0range_error@std@@QAE@ABV01@@Z */
835 /* ??0range_error@std@@QEAA@AEBV01@@Z */
836 DEFINE_THISCALL_WRAPPER(range_error_copy_ctor, 8)
837 range_error* __thiscall range_error_copy_ctor(
838 range_error *this, const range_error *rhs)
840 TRACE("%p %p\n", this, rhs);
841 runtime_error_copy_ctor(this, rhs);
842 this->e.vtable = &range_error_vtable;
843 return this;
846 /* ??0range_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
847 /* ??0range_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
848 #ifndef _MSVCIRT
849 DEFINE_THISCALL_WRAPPER(MSVCP_range_error_ctor_bstr, 8)
850 range_error* __thiscall MSVCP_range_error_ctor_bstr(range_error *this, const basic_string_char *str)
852 const char *name = MSVCP_basic_string_char_c_str(str);
853 TRACE("(%p %p %s)\n", this, str, name);
854 return MSVCP_range_error_ctor(this, EXCEPTION_NAME(name));
856 #endif
858 /* ??4range_error@std@@QAEAAV01@ABV01@@Z */
859 /* ??4range_error@std@@QEAAAEAV01@AEBV01@@Z */
860 DEFINE_THISCALL_WRAPPER(MSVCP_range_error_assign, 8)
861 range_error* __thiscall MSVCP_range_error_assign(range_error *this, const range_error *assign)
863 MSVCP_runtime_error_dtor(this);
864 return range_error_copy_ctor(this, assign);
867 DEFINE_RTTI_DATA2(range_error, 0, &runtime_error_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AVrange_error@std@@")
868 DEFINE_CXX_DATA2(range_error, &runtime_error_cxx_type_info, &exception_cxx_type_info, MSVCP_runtime_error_dtor)
870 /* ?_Nomemory@std@@YAXXZ */
871 void __cdecl DECLSPEC_NORETURN _Nomemory(void)
873 bad_alloc e;
875 TRACE("()\n");
877 MSVCP_bad_alloc_default_ctor(&e);
878 _CxxThrowException(&e, &bad_alloc_cxx_type);
881 /* ?_Xmem@tr1@std@@YAXXZ */
882 void __cdecl DECLSPEC_NORETURN _Xmem(void)
884 bad_alloc e;
886 TRACE("()\n");
888 MSVCP_bad_alloc_default_ctor(&e);
889 _CxxThrowException(&e, &bad_alloc_cxx_type);
892 /* ?_Xinvalid_argument@std@@YAXPBD@Z */
893 /* ?_Xinvalid_argument@std@@YAXPEBD@Z */
894 void __cdecl DECLSPEC_NORETURN _Xinvalid_argument(const char *str)
896 exception_name name = EXCEPTION_NAME(str);
897 invalid_argument e;
899 TRACE("(%s)\n", debugstr_a(str));
901 MSVCP_invalid_argument_ctor(&e, name);
902 _CxxThrowException(&e, &invalid_argument_cxx_type);
905 /* ?_Xlength_error@std@@YAXPBD@Z */
906 /* ?_Xlength_error@std@@YAXPEBD@Z */
907 void __cdecl DECLSPEC_NORETURN _Xlength_error(const char *str)
909 exception_name name = EXCEPTION_NAME(str);
910 length_error e;
912 TRACE("(%s)\n", debugstr_a(str));
914 MSVCP_length_error_ctor(&e, name);
915 _CxxThrowException(&e, &length_error_cxx_type);
918 /* ?_Xout_of_range@std@@YAXPBD@Z */
919 /* ?_Xout_of_range@std@@YAXPEBD@Z */
920 void __cdecl DECLSPEC_NORETURN _Xout_of_range(const char *str)
922 exception_name name = EXCEPTION_NAME(str);
923 out_of_range e;
925 TRACE("(%s)\n", debugstr_a(str));
927 MSVCP_out_of_range_ctor(&e, name);
928 _CxxThrowException(&e, &out_of_range_cxx_type);
931 /* ?_Xruntime_error@std@@YAXPBD@Z */
932 /* ?_Xruntime_error@std@@YAXPEBD@Z */
933 void __cdecl DECLSPEC_NORETURN _Xruntime_error(const char *str)
935 exception_name name = EXCEPTION_NAME(str);
936 runtime_error e;
938 TRACE("(%s)\n", debugstr_a(str));
940 MSVCP_runtime_error_ctor(&e, name);
941 _CxxThrowException(&e, &runtime_error_cxx_type);
944 /* ?uncaught_exception@std@@YA_NXZ */
945 bool __cdecl MSVCP__uncaught_exception(void)
947 return __uncaught_exception();
950 #if _MSVCP_VER >= 140
951 void** CDECL __current_exception(void);
953 /* compute the this pointer for a base class of a given type */
954 static inline void *get_this_pointer( const this_ptr_offsets *off, void *object )
956 if (!object) return NULL;
958 if (off->vbase_descr >= 0)
960 int *offset_ptr;
962 /* move this ptr to vbase descriptor */
963 object = (char *)object + off->vbase_descr;
964 /* and fetch additional offset from vbase descriptor */
965 offset_ptr = (int *)(*(char **)object + off->vbase_offset);
966 object = (char *)object + *offset_ptr;
969 object = (char *)object + off->this_offset;
970 return object;
973 #ifdef __i386__
974 extern void call_copy_ctor( void *func, void *this, void *src, int has_vbase );
975 __ASM_GLOBAL_FUNC( call_copy_ctor,
976 "pushl %ebp\n\t"
977 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
978 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
979 "movl %esp, %ebp\n\t"
980 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
981 "pushl $1\n\t"
982 "movl 12(%ebp), %ecx\n\t"
983 "pushl 16(%ebp)\n\t"
984 "call *8(%ebp)\n\t"
985 "leave\n"
986 __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
987 __ASM_CFI(".cfi_same_value %ebp\n\t")
988 "ret" );
989 #else
990 static inline void call_copy_ctor( void *func, void *this, void *src, int has_vbase )
992 TRACE( "calling copy ctor %p object %p src %p\n", func, this, src );
993 if (has_vbase)
994 ((void (__cdecl*)(void*, void*, BOOL))func)(this, src, 1);
995 else
996 ((void (__cdecl*)(void*, void*))func)(this, src);
998 #endif
1000 int __cdecl __uncaught_exceptions(void)
1002 return *__processing_throw();
1005 typedef struct
1007 EXCEPTION_RECORD *rec;
1008 LONG *ref; /* not binary compatible with native */
1009 } exception_ptr;
1011 /*********************************************************************
1012 * ?__ExceptionPtrCreate@@YAXPAX@Z
1013 * ?__ExceptionPtrCreate@@YAXPEAX@Z
1015 void __cdecl __ExceptionPtrCreate(exception_ptr *ep)
1017 TRACE("(%p)\n", ep);
1019 ep->rec = NULL;
1020 ep->ref = NULL;
1023 #ifdef __ASM_USE_THISCALL_WRAPPER
1024 extern void call_dtor(const cxx_exception_type *type, void *func, void *object);
1026 __ASM_GLOBAL_FUNC( call_dtor,
1027 "movl 12(%esp),%ecx\n\t"
1028 "call *8(%esp)\n\t"
1029 "ret" );
1030 #elif __x86_64__
1031 static inline void call_dtor(const cxx_exception_type *type, unsigned int dtor, void *object)
1033 char *base = RtlPcToFileHeader((void*)type, (void**)&base);
1034 void (__cdecl *func)(void*) = (void*)(base + dtor);
1035 func(object);
1037 #else
1038 #define call_dtor(type, func, object) ((void (__thiscall*)(void*))(func))(object)
1039 #endif
1041 /*********************************************************************
1042 * ?__ExceptionPtrDestroy@@YAXPAX@Z
1043 * ?__ExceptionPtrDestroy@@YAXPEAX@Z
1045 void __cdecl __ExceptionPtrDestroy(exception_ptr *ep)
1047 TRACE("(%p)\n", ep);
1049 if (!ep->rec)
1050 return;
1052 if (!InterlockedDecrement(ep->ref))
1054 if (ep->rec->ExceptionCode == CXX_EXCEPTION)
1056 const cxx_exception_type *type = (void*)ep->rec->ExceptionInformation[2];
1057 void *obj = (void*)ep->rec->ExceptionInformation[1];
1059 if (type && type->destructor) call_dtor(type, type->destructor, obj);
1060 HeapFree(GetProcessHeap(), 0, obj);
1063 HeapFree(GetProcessHeap(), 0, ep->rec);
1064 HeapFree(GetProcessHeap(), 0, ep->ref);
1068 /*********************************************************************
1069 * ?__ExceptionPtrCopy@@YAXPAXPBX@Z
1070 * ?__ExceptionPtrCopy@@YAXPEAXPEBX@Z
1072 void __cdecl __ExceptionPtrCopy(exception_ptr *ep, const exception_ptr *copy)
1074 TRACE("(%p %p)\n", ep, copy);
1076 /* don't destroy object stored in ep */
1077 *ep = *copy;
1078 if (ep->ref)
1079 InterlockedIncrement(copy->ref);
1082 /*********************************************************************
1083 * ?__ExceptionPtrAssign@@YAXPAXPBX@Z
1084 * ?__ExceptionPtrAssign@@YAXPEAXPEBX@Z
1086 void __cdecl __ExceptionPtrAssign(exception_ptr *ep, const exception_ptr *assign)
1088 TRACE("(%p %p)\n", ep, assign);
1090 /* don't destroy object stored in ep */
1091 if (ep->ref)
1092 InterlockedDecrement(ep->ref);
1094 *ep = *assign;
1095 if (ep->ref)
1096 InterlockedIncrement(ep->ref);
1099 /*********************************************************************
1100 * ?__ExceptionPtrRethrow@@YAXPBX@Z
1101 * ?__ExceptionPtrRethrow@@YAXPEBX@Z
1103 void __cdecl __ExceptionPtrRethrow(const exception_ptr *ep)
1105 TRACE("(%p)\n", ep);
1107 if (!ep->rec)
1109 static const char *exception_msg = "bad exception";
1110 exception e;
1112 MSVCP_exception_ctor(&e, &exception_msg);
1113 _CxxThrowException(&e, &exception_cxx_type);
1114 return;
1117 RaiseException(ep->rec->ExceptionCode, ep->rec->ExceptionFlags & (~EH_UNWINDING),
1118 ep->rec->NumberParameters, ep->rec->ExceptionInformation);
1121 /*********************************************************************
1122 * ?__ExceptionPtrCurrentException@@YAXPAX@Z
1123 * ?__ExceptionPtrCurrentException@@YAXPEAX@Z
1125 #ifndef __x86_64__
1126 void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep)
1128 void **current_exception = __current_exception();
1129 EXCEPTION_RECORD *rec = current_exception ? *current_exception : NULL;
1131 TRACE("(%p)\n", ep);
1133 if (!rec)
1135 ep->rec = NULL;
1136 ep->ref = NULL;
1137 return;
1140 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1141 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1143 *ep->rec = *rec;
1144 *ep->ref = 1;
1146 if (ep->rec->ExceptionCode == CXX_EXCEPTION)
1148 const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2];
1149 const cxx_type_info *ti;
1150 void **data, *obj;
1152 ti = et->type_info_table->info[0];
1153 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1155 obj = (void*)ep->rec->ExceptionInformation[1];
1156 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1158 memcpy(data, obj, ti->size);
1159 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1161 else if (ti->copy_ctor)
1163 call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj),
1164 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS);
1166 else
1167 memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size);
1168 ep->rec->ExceptionInformation[1] = (ULONG_PTR)data;
1170 return;
1172 #else
1173 void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep)
1175 void **current_exception = __current_exception();
1176 EXCEPTION_RECORD *rec = current_exception ? *current_exception : NULL;
1178 TRACE("(%p)\n", ep);
1180 if (!rec)
1182 ep->rec = NULL;
1183 ep->ref = NULL;
1184 return;
1187 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1188 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1190 *ep->rec = *rec;
1191 *ep->ref = 1;
1193 if (ep->rec->ExceptionCode == CXX_EXCEPTION)
1195 const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2];
1196 const cxx_type_info *ti;
1197 void **data, *obj;
1198 char *base = RtlPcToFileHeader((void*)et, (void**)&base);
1200 ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + et->type_info_table))->info[0]);
1201 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1203 obj = (void*)ep->rec->ExceptionInformation[1];
1204 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1206 memcpy(data, obj, ti->size);
1207 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1209 else if (ti->copy_ctor)
1211 call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj),
1212 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS);
1214 else
1215 memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size);
1216 ep->rec->ExceptionInformation[1] = (ULONG_PTR)data;
1218 return;
1220 #endif
1222 /*********************************************************************
1223 * ?__ExceptionPtrToBool@@YA_NPBX@Z
1224 * ?__ExceptionPtrToBool@@YA_NPEBX@Z
1226 bool __cdecl __ExceptionPtrToBool(exception_ptr *ep)
1228 return !!ep->rec;
1231 /*********************************************************************
1232 * ?__ExceptionPtrCopyException@@YAXPAXPBX1@Z
1233 * ?__ExceptionPtrCopyException@@YAXPEAXPEBX1@Z
1235 #ifndef __x86_64__
1236 void __cdecl __ExceptionPtrCopyException(exception_ptr *ep,
1237 exception *object, const cxx_exception_type *type)
1239 const cxx_type_info *ti;
1240 void **data;
1242 __ExceptionPtrDestroy(ep);
1244 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1245 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1246 *ep->ref = 1;
1248 memset(ep->rec, 0, sizeof(EXCEPTION_RECORD));
1249 ep->rec->ExceptionCode = CXX_EXCEPTION;
1250 ep->rec->ExceptionFlags = EH_NONCONTINUABLE;
1251 ep->rec->NumberParameters = 3;
1252 ep->rec->ExceptionInformation[0] = CXX_FRAME_MAGIC_VC6;
1253 ep->rec->ExceptionInformation[2] = (ULONG_PTR)type;
1255 ti = type->type_info_table->info[0];
1256 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1257 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1259 memcpy(data, object, ti->size);
1260 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1262 else if (ti->copy_ctor)
1264 call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, object),
1265 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS);
1267 else
1268 memcpy(data, get_this_pointer(&ti->offsets, object), ti->size);
1269 ep->rec->ExceptionInformation[1] = (ULONG_PTR)data;
1271 #else
1272 void __cdecl __ExceptionPtrCopyException(exception_ptr *ep,
1273 exception *object, const cxx_exception_type *type)
1275 const cxx_type_info *ti;
1276 void **data;
1277 char *base;
1279 RtlPcToFileHeader((void*)type, (void**)&base);
1280 __ExceptionPtrDestroy(ep);
1282 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1283 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1284 *ep->ref = 1;
1286 memset(ep->rec, 0, sizeof(EXCEPTION_RECORD));
1287 ep->rec->ExceptionCode = CXX_EXCEPTION;
1288 ep->rec->ExceptionFlags = EH_NONCONTINUABLE;
1289 ep->rec->NumberParameters = 4;
1290 ep->rec->ExceptionInformation[0] = CXX_FRAME_MAGIC_VC6;
1291 ep->rec->ExceptionInformation[2] = (ULONG_PTR)type;
1292 ep->rec->ExceptionInformation[3] = (ULONG_PTR)base;
1294 ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + type->type_info_table))->info[0]);
1295 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1296 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1298 memcpy(data, object, ti->size);
1299 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1301 else if (ti->copy_ctor)
1303 call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, object),
1304 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS);
1306 else
1307 memcpy(data, get_this_pointer(&ti->offsets, object), ti->size);
1308 ep->rec->ExceptionInformation[1] = (ULONG_PTR)data;
1310 #endif
1312 /*********************************************************************
1313 * ?__ExceptionPtrCompare@@YA_NPBX0@Z
1314 * ?__ExceptionPtrCompare@@YA_NPEBX0@Z
1316 bool __cdecl __ExceptionPtrCompare(const exception_ptr *ep1, const exception_ptr *ep2)
1318 return ep1->rec == ep2->rec;
1320 #endif
1322 #if _MSVCP_VER >= 70 || defined(_MSVCIRT)
1323 #define EXCEPTION_VTABLE(name,funcs) __ASM_VTABLE(name,funcs)
1324 #else
1325 #define EXCEPTION_VTABLE(name,funcs) __ASM_VTABLE(name,funcs VTABLE_ADD_FUNC(MSVCP_exception__Doraise))
1326 #endif
1328 __ASM_BLOCK_BEGIN(exception_vtables)
1329 EXCEPTION_VTABLE(exception,
1330 VTABLE_ADD_FUNC(MSVCP_exception_vector_dtor)
1331 VTABLE_ADD_FUNC(MSVCP_exception_what));
1332 EXCEPTION_VTABLE(bad_alloc,
1333 VTABLE_ADD_FUNC(MSVCP_bad_alloc_vector_dtor)
1334 VTABLE_ADD_FUNC(MSVCP_exception_what));
1335 EXCEPTION_VTABLE(logic_error,
1336 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor)
1337 VTABLE_ADD_FUNC(MSVCP_logic_error_what));
1338 EXCEPTION_VTABLE(length_error,
1339 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor)
1340 VTABLE_ADD_FUNC(MSVCP_logic_error_what));
1341 EXCEPTION_VTABLE(out_of_range,
1342 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor)
1343 VTABLE_ADD_FUNC(MSVCP_logic_error_what));
1344 EXCEPTION_VTABLE(invalid_argument,
1345 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor)
1346 VTABLE_ADD_FUNC(MSVCP_logic_error_what));
1347 EXCEPTION_VTABLE(runtime_error,
1348 VTABLE_ADD_FUNC(MSVCP_runtime_error_vector_dtor)
1349 VTABLE_ADD_FUNC(MSVCP_runtime_error_what));
1350 #if _MSVCP_VER > 110
1351 EXCEPTION_VTABLE(_System_error,
1352 VTABLE_ADD_FUNC(MSVCP_failure_vector_dtor)
1353 VTABLE_ADD_FUNC(MSVCP_failure_what));
1354 #endif
1355 #if _MSVCP_VER > 90
1356 EXCEPTION_VTABLE(system_error,
1357 VTABLE_ADD_FUNC(MSVCP_failure_vector_dtor)
1358 VTABLE_ADD_FUNC(MSVCP_failure_what));
1359 #endif
1360 EXCEPTION_VTABLE(failure,
1361 VTABLE_ADD_FUNC(MSVCP_failure_vector_dtor)
1362 VTABLE_ADD_FUNC(MSVCP_failure_what));
1363 EXCEPTION_VTABLE(bad_cast,
1364 VTABLE_ADD_FUNC(MSVCP_bad_cast_vector_dtor)
1365 VTABLE_ADD_FUNC(MSVCP_exception_what));
1366 EXCEPTION_VTABLE(range_error,
1367 VTABLE_ADD_FUNC(MSVCP_runtime_error_vector_dtor)
1368 VTABLE_ADD_FUNC(MSVCP_runtime_error_what));
1369 __ASM_BLOCK_END
1371 /* Internal: throws exception */
1372 void DECLSPEC_NORETURN throw_exception(const char *str)
1374 exception_name name = EXCEPTION_NAME(str);
1375 exception e;
1377 MSVCP_exception_ctor(&e, name);
1378 _CxxThrowException(&e, &exception_cxx_type);
1381 /* Internal: throws range_error exception */
1382 void DECLSPEC_NORETURN throw_range_error(const char *str)
1384 exception_name name = EXCEPTION_NAME(str);
1385 range_error e;
1387 MSVCP_range_error_ctor(&e, name);
1388 _CxxThrowException(&e, &range_error_cxx_type);
1391 /* Internal: throws failure exception */
1392 void DECLSPEC_NORETURN throw_failure(const char *str)
1394 exception_name name = EXCEPTION_NAME(str);
1395 failure e;
1397 MSVCP_failure_ctor(&e, name);
1398 _CxxThrowException(&e, &failure_cxx_type);
1401 void init_exception(void *base)
1403 #ifdef __x86_64__
1404 init_type_info_rtti(base);
1405 init_exception_rtti(base);
1406 init_bad_alloc_rtti(base);
1407 init_logic_error_rtti(base);
1408 init_length_error_rtti(base);
1409 init_out_of_range_rtti(base);
1410 init_invalid_argument_rtti(base);
1411 init_runtime_error_rtti(base);
1412 #if _MSVCP_VER > 110
1413 init__System_error_rtti(base);
1414 #endif
1415 #if _MSVCP_VER > 90
1416 init_system_error_rtti(base);
1417 #endif
1418 init_failure_rtti(base);
1419 init_bad_cast_rtti(base);
1420 init_range_error_rtti(base);
1422 init_exception_cxx(base);
1423 init_bad_alloc_cxx(base);
1424 init_logic_error_cxx_type_info(base);
1425 init_length_error_cxx(base);
1426 init_out_of_range_cxx(base);
1427 init_invalid_argument_cxx(base);
1428 init_runtime_error_cxx(base);
1429 #if _MSVCP_VER > 110
1430 init__System_error_cxx_type_info(base);
1431 #endif
1432 #if _MSVCP_VER > 90
1433 init_system_error_cxx_type_info(base);
1434 #endif
1435 init_failure_cxx(base);
1436 init_range_error_cxx(base);
1437 #endif