include: Add some new ProcThreadAttribute definitions.
[wine.git] / dlls / msvcp90 / exception.c
blob66a5061a4f0097ff3a9b3466a1d1eee84685454b
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 >= 110
951 typedef struct
953 EXCEPTION_RECORD *rec;
954 LONG *ref; /* not binary compatible with native */
955 } exception_ptr;
957 static void exception_ptr_rethrow(const exception_ptr *ep)
959 TRACE("(%p)\n", ep);
961 if (!ep->rec)
963 static const char *exception_msg = "bad exception";
964 exception e;
966 MSVCP_exception_ctor(&e, &exception_msg);
967 _CxxThrowException(&e, &exception_cxx_type);
968 return;
971 RaiseException(ep->rec->ExceptionCode, ep->rec->ExceptionFlags & (~EH_UNWINDING),
972 ep->rec->NumberParameters, ep->rec->ExceptionInformation);
975 /* ?_Rethrow_future_exception@std@@YAXVexception_ptr@1@@Z */
976 void __cdecl _Rethrow_future_exception(const exception_ptr ep)
978 exception_ptr_rethrow(&ep);
980 #endif
982 #if _MSVCP_VER >= 140
983 void** CDECL __current_exception(void);
985 /* compute the this pointer for a base class of a given type */
986 static inline void *get_this_pointer( const this_ptr_offsets *off, void *object )
988 if (!object) return NULL;
990 if (off->vbase_descr >= 0)
992 int *offset_ptr;
994 /* move this ptr to vbase descriptor */
995 object = (char *)object + off->vbase_descr;
996 /* and fetch additional offset from vbase descriptor */
997 offset_ptr = (int *)(*(char **)object + off->vbase_offset);
998 object = (char *)object + *offset_ptr;
1001 object = (char *)object + off->this_offset;
1002 return object;
1005 #ifdef __i386__
1006 extern void call_copy_ctor( void *func, void *this, void *src, int has_vbase );
1007 __ASM_GLOBAL_FUNC( call_copy_ctor,
1008 "pushl %ebp\n\t"
1009 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
1010 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
1011 "movl %esp, %ebp\n\t"
1012 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
1013 "pushl $1\n\t"
1014 "movl 12(%ebp), %ecx\n\t"
1015 "pushl 16(%ebp)\n\t"
1016 "call *8(%ebp)\n\t"
1017 "leave\n"
1018 __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
1019 __ASM_CFI(".cfi_same_value %ebp\n\t")
1020 "ret" );
1021 #else
1022 static inline void call_copy_ctor( void *func, void *this, void *src, int has_vbase )
1024 TRACE( "calling copy ctor %p object %p src %p\n", func, this, src );
1025 if (has_vbase)
1026 ((void (__cdecl*)(void*, void*, BOOL))func)(this, src, 1);
1027 else
1028 ((void (__cdecl*)(void*, void*))func)(this, src);
1030 #endif
1032 int __cdecl __uncaught_exceptions(void)
1034 return *__processing_throw();
1037 /*********************************************************************
1038 * ?__ExceptionPtrCreate@@YAXPAX@Z
1039 * ?__ExceptionPtrCreate@@YAXPEAX@Z
1041 void __cdecl __ExceptionPtrCreate(exception_ptr *ep)
1043 TRACE("(%p)\n", ep);
1045 ep->rec = NULL;
1046 ep->ref = NULL;
1049 #ifdef __ASM_USE_THISCALL_WRAPPER
1050 extern void call_dtor(const cxx_exception_type *type, void *func, void *object);
1052 __ASM_GLOBAL_FUNC( call_dtor,
1053 "movl 12(%esp),%ecx\n\t"
1054 "call *8(%esp)\n\t"
1055 "ret" );
1056 #elif __x86_64__
1057 static inline void call_dtor(const cxx_exception_type *type, unsigned int dtor, void *object)
1059 char *base = RtlPcToFileHeader((void*)type, (void**)&base);
1060 void (__cdecl *func)(void*) = (void*)(base + dtor);
1061 func(object);
1063 #else
1064 #define call_dtor(type, func, object) ((void (__thiscall*)(void*))(func))(object)
1065 #endif
1067 /*********************************************************************
1068 * ?__ExceptionPtrDestroy@@YAXPAX@Z
1069 * ?__ExceptionPtrDestroy@@YAXPEAX@Z
1071 void __cdecl __ExceptionPtrDestroy(exception_ptr *ep)
1073 TRACE("(%p)\n", ep);
1075 if (!ep->rec)
1076 return;
1078 if (!InterlockedDecrement(ep->ref))
1080 if (ep->rec->ExceptionCode == CXX_EXCEPTION)
1082 const cxx_exception_type *type = (void*)ep->rec->ExceptionInformation[2];
1083 void *obj = (void*)ep->rec->ExceptionInformation[1];
1085 if (type && type->destructor) call_dtor(type, type->destructor, obj);
1086 HeapFree(GetProcessHeap(), 0, obj);
1089 HeapFree(GetProcessHeap(), 0, ep->rec);
1090 HeapFree(GetProcessHeap(), 0, ep->ref);
1094 /*********************************************************************
1095 * ?__ExceptionPtrCopy@@YAXPAXPBX@Z
1096 * ?__ExceptionPtrCopy@@YAXPEAXPEBX@Z
1098 void __cdecl __ExceptionPtrCopy(exception_ptr *ep, const exception_ptr *copy)
1100 TRACE("(%p %p)\n", ep, copy);
1102 /* don't destroy object stored in ep */
1103 *ep = *copy;
1104 if (ep->ref)
1105 InterlockedIncrement(copy->ref);
1108 /*********************************************************************
1109 * ?__ExceptionPtrAssign@@YAXPAXPBX@Z
1110 * ?__ExceptionPtrAssign@@YAXPEAXPEBX@Z
1112 void __cdecl __ExceptionPtrAssign(exception_ptr *ep, const exception_ptr *assign)
1114 TRACE("(%p %p)\n", ep, assign);
1116 /* don't destroy object stored in ep */
1117 if (ep->ref)
1118 InterlockedDecrement(ep->ref);
1120 *ep = *assign;
1121 if (ep->ref)
1122 InterlockedIncrement(ep->ref);
1125 /*********************************************************************
1126 * ?__ExceptionPtrRethrow@@YAXPBX@Z
1127 * ?__ExceptionPtrRethrow@@YAXPEBX@Z
1129 void __cdecl __ExceptionPtrRethrow(const exception_ptr *ep)
1131 exception_ptr_rethrow(ep);
1134 /*********************************************************************
1135 * ?__ExceptionPtrCurrentException@@YAXPAX@Z
1136 * ?__ExceptionPtrCurrentException@@YAXPEAX@Z
1138 #ifndef __x86_64__
1139 void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep)
1141 void **current_exception = __current_exception();
1142 EXCEPTION_RECORD *rec = current_exception ? *current_exception : NULL;
1144 TRACE("(%p)\n", ep);
1146 if (!rec)
1148 ep->rec = NULL;
1149 ep->ref = NULL;
1150 return;
1153 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1154 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1156 *ep->rec = *rec;
1157 *ep->ref = 1;
1159 if (ep->rec->ExceptionCode == CXX_EXCEPTION)
1161 const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2];
1162 const cxx_type_info *ti;
1163 void **data, *obj;
1165 ti = et->type_info_table->info[0];
1166 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1168 obj = (void*)ep->rec->ExceptionInformation[1];
1169 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1171 memcpy(data, obj, ti->size);
1172 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1174 else if (ti->copy_ctor)
1176 call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj),
1177 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS);
1179 else
1180 memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size);
1181 ep->rec->ExceptionInformation[1] = (ULONG_PTR)data;
1183 return;
1185 #else
1186 void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep)
1188 void **current_exception = __current_exception();
1189 EXCEPTION_RECORD *rec = current_exception ? *current_exception : NULL;
1191 TRACE("(%p)\n", ep);
1193 if (!rec)
1195 ep->rec = NULL;
1196 ep->ref = NULL;
1197 return;
1200 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1201 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1203 *ep->rec = *rec;
1204 *ep->ref = 1;
1206 if (ep->rec->ExceptionCode == CXX_EXCEPTION)
1208 const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2];
1209 const cxx_type_info *ti;
1210 void **data, *obj;
1211 char *base = RtlPcToFileHeader((void*)et, (void**)&base);
1213 ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + et->type_info_table))->info[0]);
1214 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1216 obj = (void*)ep->rec->ExceptionInformation[1];
1217 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1219 memcpy(data, obj, ti->size);
1220 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1222 else if (ti->copy_ctor)
1224 call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj),
1225 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS);
1227 else
1228 memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size);
1229 ep->rec->ExceptionInformation[1] = (ULONG_PTR)data;
1231 return;
1233 #endif
1235 /*********************************************************************
1236 * ?__ExceptionPtrToBool@@YA_NPBX@Z
1237 * ?__ExceptionPtrToBool@@YA_NPEBX@Z
1239 bool __cdecl __ExceptionPtrToBool(exception_ptr *ep)
1241 return !!ep->rec;
1244 /*********************************************************************
1245 * ?__ExceptionPtrCopyException@@YAXPAXPBX1@Z
1246 * ?__ExceptionPtrCopyException@@YAXPEAXPEBX1@Z
1248 #ifndef __x86_64__
1249 void __cdecl __ExceptionPtrCopyException(exception_ptr *ep,
1250 exception *object, const cxx_exception_type *type)
1252 const cxx_type_info *ti;
1253 void **data;
1255 __ExceptionPtrDestroy(ep);
1257 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1258 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1259 *ep->ref = 1;
1261 memset(ep->rec, 0, sizeof(EXCEPTION_RECORD));
1262 ep->rec->ExceptionCode = CXX_EXCEPTION;
1263 ep->rec->ExceptionFlags = EH_NONCONTINUABLE;
1264 ep->rec->NumberParameters = 3;
1265 ep->rec->ExceptionInformation[0] = CXX_FRAME_MAGIC_VC6;
1266 ep->rec->ExceptionInformation[2] = (ULONG_PTR)type;
1268 ti = type->type_info_table->info[0];
1269 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1270 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1272 memcpy(data, object, ti->size);
1273 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1275 else if (ti->copy_ctor)
1277 call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, object),
1278 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS);
1280 else
1281 memcpy(data, get_this_pointer(&ti->offsets, object), ti->size);
1282 ep->rec->ExceptionInformation[1] = (ULONG_PTR)data;
1284 #else
1285 void __cdecl __ExceptionPtrCopyException(exception_ptr *ep,
1286 exception *object, const cxx_exception_type *type)
1288 const cxx_type_info *ti;
1289 void **data;
1290 char *base;
1292 RtlPcToFileHeader((void*)type, (void**)&base);
1293 __ExceptionPtrDestroy(ep);
1295 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1296 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1297 *ep->ref = 1;
1299 memset(ep->rec, 0, sizeof(EXCEPTION_RECORD));
1300 ep->rec->ExceptionCode = CXX_EXCEPTION;
1301 ep->rec->ExceptionFlags = EH_NONCONTINUABLE;
1302 ep->rec->NumberParameters = 4;
1303 ep->rec->ExceptionInformation[0] = CXX_FRAME_MAGIC_VC6;
1304 ep->rec->ExceptionInformation[2] = (ULONG_PTR)type;
1305 ep->rec->ExceptionInformation[3] = (ULONG_PTR)base;
1307 ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + type->type_info_table))->info[0]);
1308 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1309 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1311 memcpy(data, object, ti->size);
1312 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1314 else if (ti->copy_ctor)
1316 call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, object),
1317 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS);
1319 else
1320 memcpy(data, get_this_pointer(&ti->offsets, object), ti->size);
1321 ep->rec->ExceptionInformation[1] = (ULONG_PTR)data;
1323 #endif
1325 /*********************************************************************
1326 * ?__ExceptionPtrCompare@@YA_NPBX0@Z
1327 * ?__ExceptionPtrCompare@@YA_NPEBX0@Z
1329 bool __cdecl __ExceptionPtrCompare(const exception_ptr *ep1, const exception_ptr *ep2)
1331 return ep1->rec == ep2->rec;
1333 #endif
1335 #if _MSVCP_VER >= 70 || defined(_MSVCIRT)
1336 #define EXCEPTION_VTABLE(name,funcs) __ASM_VTABLE(name,funcs)
1337 #else
1338 #define EXCEPTION_VTABLE(name,funcs) __ASM_VTABLE(name,funcs VTABLE_ADD_FUNC(MSVCP_exception__Doraise))
1339 #endif
1341 __ASM_BLOCK_BEGIN(exception_vtables)
1342 EXCEPTION_VTABLE(exception,
1343 VTABLE_ADD_FUNC(MSVCP_exception_vector_dtor)
1344 VTABLE_ADD_FUNC(MSVCP_exception_what));
1345 EXCEPTION_VTABLE(bad_alloc,
1346 VTABLE_ADD_FUNC(MSVCP_bad_alloc_vector_dtor)
1347 VTABLE_ADD_FUNC(MSVCP_exception_what));
1348 EXCEPTION_VTABLE(logic_error,
1349 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor)
1350 VTABLE_ADD_FUNC(MSVCP_logic_error_what));
1351 EXCEPTION_VTABLE(length_error,
1352 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor)
1353 VTABLE_ADD_FUNC(MSVCP_logic_error_what));
1354 EXCEPTION_VTABLE(out_of_range,
1355 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor)
1356 VTABLE_ADD_FUNC(MSVCP_logic_error_what));
1357 EXCEPTION_VTABLE(invalid_argument,
1358 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor)
1359 VTABLE_ADD_FUNC(MSVCP_logic_error_what));
1360 EXCEPTION_VTABLE(runtime_error,
1361 VTABLE_ADD_FUNC(MSVCP_runtime_error_vector_dtor)
1362 VTABLE_ADD_FUNC(MSVCP_runtime_error_what));
1363 #if _MSVCP_VER > 110
1364 EXCEPTION_VTABLE(_System_error,
1365 VTABLE_ADD_FUNC(MSVCP_failure_vector_dtor)
1366 VTABLE_ADD_FUNC(MSVCP_failure_what));
1367 #endif
1368 #if _MSVCP_VER > 90
1369 EXCEPTION_VTABLE(system_error,
1370 VTABLE_ADD_FUNC(MSVCP_failure_vector_dtor)
1371 VTABLE_ADD_FUNC(MSVCP_failure_what));
1372 #endif
1373 EXCEPTION_VTABLE(failure,
1374 VTABLE_ADD_FUNC(MSVCP_failure_vector_dtor)
1375 VTABLE_ADD_FUNC(MSVCP_failure_what));
1376 EXCEPTION_VTABLE(bad_cast,
1377 VTABLE_ADD_FUNC(MSVCP_bad_cast_vector_dtor)
1378 VTABLE_ADD_FUNC(MSVCP_exception_what));
1379 EXCEPTION_VTABLE(range_error,
1380 VTABLE_ADD_FUNC(MSVCP_runtime_error_vector_dtor)
1381 VTABLE_ADD_FUNC(MSVCP_runtime_error_what));
1382 __ASM_BLOCK_END
1384 /* Internal: throws exception */
1385 void DECLSPEC_NORETURN throw_exception(const char *str)
1387 exception_name name = EXCEPTION_NAME(str);
1388 exception e;
1390 MSVCP_exception_ctor(&e, name);
1391 _CxxThrowException(&e, &exception_cxx_type);
1394 /* Internal: throws range_error exception */
1395 void DECLSPEC_NORETURN throw_range_error(const char *str)
1397 exception_name name = EXCEPTION_NAME(str);
1398 range_error e;
1400 MSVCP_range_error_ctor(&e, name);
1401 _CxxThrowException(&e, &range_error_cxx_type);
1404 /* Internal: throws failure exception */
1405 void DECLSPEC_NORETURN throw_failure(const char *str)
1407 exception_name name = EXCEPTION_NAME(str);
1408 failure e;
1410 MSVCP_failure_ctor(&e, name);
1411 _CxxThrowException(&e, &failure_cxx_type);
1414 void init_exception(void *base)
1416 #ifdef __x86_64__
1417 init_type_info_rtti(base);
1418 init_exception_rtti(base);
1419 init_bad_alloc_rtti(base);
1420 init_logic_error_rtti(base);
1421 init_length_error_rtti(base);
1422 init_out_of_range_rtti(base);
1423 init_invalid_argument_rtti(base);
1424 init_runtime_error_rtti(base);
1425 #if _MSVCP_VER > 110
1426 init__System_error_rtti(base);
1427 #endif
1428 #if _MSVCP_VER > 90
1429 init_system_error_rtti(base);
1430 #endif
1431 init_failure_rtti(base);
1432 init_bad_cast_rtti(base);
1433 init_range_error_rtti(base);
1435 init_exception_cxx(base);
1436 init_bad_alloc_cxx(base);
1437 init_logic_error_cxx_type_info(base);
1438 init_length_error_cxx(base);
1439 init_out_of_range_cxx(base);
1440 init_invalid_argument_cxx(base);
1441 init_runtime_error_cxx(base);
1442 #if _MSVCP_VER > 110
1443 init__System_error_cxx_type_info(base);
1444 #endif
1445 #if _MSVCP_VER > 90
1446 init_system_error_cxx_type_info(base);
1447 #endif
1448 init_failure_cxx(base);
1449 init_range_error_cxx(base);
1450 #endif