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
26 #include "wine/debug.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(msvcp
);
29 #define CLASS_IS_SIMPLE_TYPE 1
30 #define CLASS_HAS_VIRTUAL_BASE_CLASS 4
32 void WINAPI
_CxxThrowException(exception
*,const cxx_exception_type
*);
34 #if _MSVCP_VER >= 70 || defined(_MSVCIRT)
35 typedef const char **exception_name
;
36 #define EXCEPTION_STR(name) (*name)
37 #define EXCEPTION_NAME(str) ((exception_name)&str)
39 typedef const char *exception_name
;
40 #define EXCEPTION_STR(name) (name)
41 #define EXCEPTION_NAME(str) (str)
44 void (CDECL
*_Raise_handler
)(const exception
*) = NULL
;
47 extern const vtable_ptr MSVCP_exception_vtable
;
48 /* ??_7bad_alloc@std@@6B@ */
49 extern const vtable_ptr MSVCP_bad_alloc_vtable
;
50 /* ??_7logic_error@std@@6B@ */
51 extern const vtable_ptr MSVCP_logic_error_vtable
;
52 /* ??_7length_error@std@@6B@ */
53 extern const vtable_ptr MSVCP_length_error_vtable
;
54 /* ??_7out_of_range@std@@6B@ */
55 extern const vtable_ptr MSVCP_out_of_range_vtable
;
56 extern const vtable_ptr MSVCP_invalid_argument_vtable
;
57 /* ??_7runtime_error@std@@6B@ */
58 extern const vtable_ptr MSVCP_runtime_error_vtable
;
59 extern const vtable_ptr MSVCP_failure_vtable
;
60 /* ??_7bad_cast@std@@6B@ */
61 extern const vtable_ptr MSVCP_bad_cast_vtable
;
62 /* ??_7range_error@std@@6B@ */
63 extern const vtable_ptr MSVCP_range_error_vtable
;
65 static void MSVCP_type_info_dtor(type_info
* _this
)
71 DEFINE_THISCALL_WRAPPER(MSVCP_type_info_vector_dtor
,8)
72 void * __thiscall
MSVCP_type_info_vector_dtor(type_info
* _this
, unsigned int flags
)
74 TRACE("(%p %x)\n", _this
, flags
);
77 /* we have an array, with the number of elements stored before the first object */
78 INT_PTR i
, *ptr
= (INT_PTR
*)_this
- 1;
80 for (i
= *ptr
- 1; i
>= 0; i
--) MSVCP_type_info_dtor(_this
+ i
);
81 MSVCRT_operator_delete(ptr
);
85 MSVCP_type_info_dtor(_this
);
86 if (flags
& 1) MSVCRT_operator_delete(_this
);
91 DEFINE_RTTI_DATA0( type_info
, 0, ".?AVtype_info@@" )
93 /* ??0exception@@QAE@ABQBD@Z */
94 /* ??0exception@@QEAA@AEBQEBD@Z */
95 DEFINE_THISCALL_WRAPPER(MSVCP_exception_ctor
,8)
96 exception
* __thiscall
MSVCP_exception_ctor(exception
*this, exception_name name
)
98 TRACE("(%p %s)\n", this, EXCEPTION_STR(name
));
100 this->vtable
= &MSVCP_exception_vtable
;
101 if(EXCEPTION_STR(name
)) {
102 unsigned int name_len
= strlen(EXCEPTION_STR(name
)) + 1;
103 this->name
= malloc(name_len
);
104 memcpy(this->name
, EXCEPTION_STR(name
), name_len
);
105 this->do_free
= TRUE
;
108 this->do_free
= FALSE
;
113 DEFINE_THISCALL_WRAPPER(MSVCP_exception_copy_ctor
,8)
114 exception
* __thiscall
MSVCP_exception_copy_ctor(exception
*this, const exception
*rhs
)
116 TRACE("(%p,%p)\n", this, rhs
);
119 this->vtable
= &MSVCP_exception_vtable
;
120 this->name
= rhs
->name
;
121 this->do_free
= FALSE
;
123 MSVCP_exception_ctor(this, EXCEPTION_NAME(rhs
->name
));
124 TRACE("name = %s\n", this->name
);
128 /* ??0exception@@QAE@XZ */
129 /* ??0exception@@QEAA@XZ */
130 DEFINE_THISCALL_WRAPPER(MSVCP_exception_default_ctor
,4)
131 exception
* __thiscall
MSVCP_exception_default_ctor(exception
*this)
133 TRACE("(%p)\n", this);
134 this->vtable
= &MSVCP_exception_vtable
;
136 this->do_free
= FALSE
;
140 DEFINE_THISCALL_WRAPPER(MSVCP_exception_dtor
,4)
141 void __thiscall
MSVCP_exception_dtor(exception
*this)
143 TRACE("(%p)\n", this);
144 this->vtable
= &MSVCP_exception_vtable
;
149 DEFINE_THISCALL_WRAPPER(MSVCP_exception_vector_dtor
, 8)
150 void * __thiscall
MSVCP_exception_vector_dtor(exception
*this, unsigned int flags
)
152 TRACE("%p %x\n", this, flags
);
154 /* we have an array, with the number of elements stored before the first object */
155 INT_PTR i
, *ptr
= (INT_PTR
*)this-1;
157 for(i
=*ptr
-1; i
>=0; i
--)
158 MSVCP_exception_dtor(this+i
);
159 MSVCRT_operator_delete(ptr
);
161 MSVCP_exception_dtor(this);
163 MSVCRT_operator_delete(this);
169 /* ??_Gexception@@UAEPAXI@Z */
170 DEFINE_THISCALL_WRAPPER(MSVCP_exception_scalar_dtor
, 8)
171 void * __thiscall
MSVCP_exception_scalar_dtor(exception
*this, unsigned int flags
)
173 TRACE("(%p %x)\n", this, flags
);
174 MSVCP_exception_dtor(this);
175 if (flags
& 1) MSVCRT_operator_delete(this);
179 /* ??4exception@@QAEAAV0@ABV0@@Z */
180 /* ??4exception@@QEAAAEAV0@AEBV0@@Z */
181 DEFINE_THISCALL_WRAPPER(MSVCP_exception_assign
, 8)
182 exception
* __thiscall
MSVCP_exception_assign(exception
*this, const exception
*assign
)
184 MSVCP_exception_dtor(this);
185 return MSVCP_exception_copy_ctor(this, assign
);
188 /* ?_Doraise@bad_alloc@std@@MBEXXZ */
189 /* ?_Doraise@bad_alloc@std@@MEBAXXZ */
190 /* ?_Doraise@logic_error@std@@MBEXXZ */
191 /* ?_Doraise@logic_error@std@@MEBAXXZ */
192 /* ?_Doraise@length_error@std@@MBEXXZ */
193 /* ?_Doraise@length_error@std@@MEBAXXZ */
194 /* ?_Doraise@out_of_range@std@@MBEXXZ */
195 /* ?_Doraise@out_of_range@std@@MEBAXXZ */
196 /* ?_Doraise@runtime_error@std@@MBEXXZ */
197 /* ?_Doraise@runtime_error@std@@MEBAXXZ */
198 /* ?_Doraise@bad_cast@std@@MBEXXZ */
199 /* ?_Doraise@bad_cast@std@@MEBAXXZ */
200 /* ?_Doraise@range_error@std@@MBEXXZ */
201 /* ?_Doraise@range_error@std@@MEBAXXZ */
202 DEFINE_THISCALL_WRAPPER(MSVCP_exception__Doraise
, 4)
203 void __thiscall
MSVCP_exception__Doraise(exception
*this)
205 FIXME("(%p) stub\n", this);
208 DEFINE_THISCALL_WRAPPER(MSVCP_exception_what
,4)
209 const char* __thiscall
MSVCP_exception_what(exception
* this)
211 TRACE("(%p) returning %s\n", this, this->name
);
212 return this->name
? this->name
: "Unknown exception";
216 DEFINE_RTTI_DATA0(exception
, 0, ".?AVexception@std@@")
218 DEFINE_RTTI_DATA0(exception
, 0, ".?AVexception@@")
220 DEFINE_CXX_DATA0(exception
, MSVCP_exception_dtor
)
222 /* bad_alloc class data */
223 typedef exception bad_alloc
;
225 /* ??0bad_alloc@std@@QAE@PBD@Z */
226 /* ??0bad_alloc@std@@QEAA@PEBD@Z */
227 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_ctor
, 8)
228 bad_alloc
* __thiscall
MSVCP_bad_alloc_ctor(bad_alloc
*this, exception_name name
)
230 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
231 MSVCP_exception_ctor(this, name
);
232 this->vtable
= &MSVCP_bad_alloc_vtable
;
236 /* ??0bad_alloc@std@@QAE@XZ */
237 /* ??0bad_alloc@std@@QEAA@XZ */
238 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_default_ctor
, 4)
239 bad_alloc
* __thiscall
MSVCP_bad_alloc_default_ctor(bad_alloc
*this)
241 static const char name
[] = "bad allocation";
242 return MSVCP_bad_alloc_ctor(this, EXCEPTION_NAME(name
));
245 /* ??0bad_alloc@std@@QAE@ABV01@@Z */
246 /* ??0bad_alloc@std@@QEAA@AEBV01@@Z */
247 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_copy_ctor
, 8)
248 bad_alloc
* __thiscall
MSVCP_bad_alloc_copy_ctor(bad_alloc
*this, const bad_alloc
*rhs
)
250 TRACE("%p %p\n", this, rhs
);
251 MSVCP_exception_copy_ctor(this, rhs
);
252 this->vtable
= &MSVCP_bad_alloc_vtable
;
256 /* ??1bad_alloc@std@@UAE@XZ */
257 /* ??1bad_alloc@std@@UEAA@XZ */
258 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_dtor
, 4)
259 void __thiscall
MSVCP_bad_alloc_dtor(bad_alloc
*this)
262 MSVCP_exception_dtor(this);
265 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_vector_dtor
, 8)
266 void * __thiscall
MSVCP_bad_alloc_vector_dtor(bad_alloc
*this, unsigned int flags
)
268 TRACE("%p %x\n", this, flags
);
270 /* we have an array, with the number of elements stored before the first object */
271 INT_PTR i
, *ptr
= (INT_PTR
*)this-1;
273 for(i
=*ptr
-1; i
>=0; i
--)
274 MSVCP_bad_alloc_dtor(this+i
);
275 MSVCRT_operator_delete(ptr
);
277 MSVCP_bad_alloc_dtor(this);
279 MSVCRT_operator_delete(this);
285 /* ??4bad_alloc@std@@QAEAAV01@ABV01@@Z */
286 /* ??4bad_alloc@std@@QEAAAEAV01@AEBV01@@Z */
287 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_assign
, 8)
288 bad_alloc
* __thiscall
MSVCP_bad_alloc_assign(bad_alloc
*this, const bad_alloc
*assign
)
290 MSVCP_bad_alloc_dtor(this);
291 return MSVCP_bad_alloc_copy_ctor(this, assign
);
294 DEFINE_RTTI_DATA1(bad_alloc
, 0, &exception_rtti_base_descriptor
, ".?AVbad_alloc@std@@")
295 DEFINE_CXX_DATA1(bad_alloc
, &exception_cxx_type_info
, MSVCP_bad_alloc_dtor
)
297 /* logic_error class data */
300 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
301 basic_string_char str
;
305 /* ??0logic_error@@QAE@ABQBD@Z */
306 /* ??0logic_error@@QEAA@AEBQEBD@Z */
307 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_ctor
, 8)
308 logic_error
* __thiscall
MSVCP_logic_error_ctor( logic_error
*this, exception_name name
)
310 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
311 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
313 MSVCP_exception_ctor(&this->e
, "");
315 MSVCP_exception_ctor(&this->e
, NULL
);
317 MSVCP_basic_string_char_ctor_cstr(&this->str
, EXCEPTION_STR(name
));
319 MSVCP_exception_ctor(&this->e
, name
);
321 this->e
.vtable
= &MSVCP_logic_error_vtable
;
325 /* ??0logic_error@std@@QAE@ABV01@@Z */
326 /* ??0logic_error@std@@QEAA@AEBV01@@Z */
327 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_copy_ctor
, 8)
328 logic_error
* __thiscall
MSVCP_logic_error_copy_ctor(
329 logic_error
*this, const logic_error
*rhs
)
331 TRACE("%p %p\n", this, rhs
);
332 MSVCP_exception_copy_ctor(&this->e
, &rhs
->e
);
333 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
334 MSVCP_basic_string_char_copy_ctor(&this->str
, &rhs
->str
);
336 this->e
.vtable
= &MSVCP_logic_error_vtable
;
340 /* ??0logic_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
341 /* ??0logic_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
343 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_ctor_bstr
, 8)
344 logic_error
* __thiscall
MSVCP_logic_error_ctor_bstr(logic_error
*this, const basic_string_char
*str
)
346 const char *name
= MSVCP_basic_string_char_c_str(str
);
347 TRACE("(%p %p %s)\n", this, str
, name
);
348 return MSVCP_logic_error_ctor(this, EXCEPTION_NAME(name
));
352 /* ??1logic_error@std@@UAE@XZ */
353 /* ??1logic_error@std@@UEAA@XZ */
354 /* ??1length_error@std@@UAE@XZ */
355 /* ??1length_error@std@@UEAA@XZ */
356 /* ??1out_of_range@std@@UAE@XZ */
357 /* ??1out_of_range@std@@UEAA@XZ */
358 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_dtor
, 4)
359 void __thiscall
MSVCP_logic_error_dtor(logic_error
*this)
362 MSVCP_exception_dtor(&this->e
);
363 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
364 MSVCP_basic_string_char_dtor(&this->str
);
368 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_vector_dtor
, 8)
369 void* __thiscall
MSVCP_logic_error_vector_dtor(
370 logic_error
*this, unsigned int flags
)
372 TRACE("%p %x\n", this, flags
);
374 /* we have an array, with the number of elements stored before the first object */
375 INT_PTR i
, *ptr
= (INT_PTR
*)this-1;
377 for(i
=*ptr
-1; i
>=0; i
--)
378 MSVCP_logic_error_dtor(this+i
);
379 MSVCRT_operator_delete(ptr
);
381 MSVCP_logic_error_dtor(this);
383 MSVCRT_operator_delete(this);
389 /* ??_Glogic_error@@UAEPAXI@Z */
390 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_scalar_dtor
, 8)
391 void * __thiscall
MSVCP_logic_error_scalar_dtor(logic_error
*this, unsigned int flags
)
393 TRACE("(%p %x)\n", this, flags
);
394 MSVCP_logic_error_dtor(this);
395 if (flags
& 1) MSVCRT_operator_delete(this);
399 /* ??4logic_error@std@@QAEAAV01@ABV01@@Z */
400 /* ??4logic_error@std@@QEAAAEAV01@AEBV01@@Z */
401 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_assign
, 8)
402 logic_error
* __thiscall
MSVCP_logic_error_assign(logic_error
*this, const logic_error
*assign
)
404 MSVCP_logic_error_dtor(this);
405 return MSVCP_logic_error_copy_ctor(this, assign
);
408 /* ?what@logic_error@std@@UBEPBDXZ */
409 /* ?what@logic_error@std@@UEBAPEBDXZ */
410 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_what
, 4)
411 const char* __thiscall
MSVCP_logic_error_what(logic_error
*this)
414 #if _MSVCP_VER > 90 || defined _MSVCIRT
415 return MSVCP_exception_what( &this->e
);
417 return MSVCP_basic_string_char_c_str(&this->str
);
422 DEFINE_RTTI_DATA1(logic_error
, 0, &exception_rtti_base_descriptor
, ".?AVlogic_error@std@@")
424 DEFINE_RTTI_DATA1(logic_error
, 0, &exception_rtti_base_descriptor
, ".?AVlogic_error@@")
426 DEFINE_CXX_DATA1(logic_error
, &exception_cxx_type_info
, MSVCP_logic_error_dtor
)
428 /* length_error class data */
429 typedef logic_error length_error
;
431 static length_error
* MSVCP_length_error_ctor( length_error
*this, exception_name name
)
433 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
434 MSVCP_logic_error_ctor(this, name
);
435 this->e
.vtable
= &MSVCP_length_error_vtable
;
439 /* ??0length_error@std@@QAE@ABV01@@Z */
440 /* ??0length_error@std@@QEAA@AEBV01@@Z */
441 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_copy_ctor
, 8)
442 length_error
* __thiscall
MSVCP_length_error_copy_ctor(
443 length_error
*this, const length_error
*rhs
)
445 TRACE("%p %p\n", this, rhs
);
446 MSVCP_logic_error_copy_ctor(this, rhs
);
447 this->e
.vtable
= &MSVCP_length_error_vtable
;
451 /* ??0length_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
452 /* ??0length_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
454 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_ctor_bstr
, 8)
455 length_error
* __thiscall
MSVCP_length_error_ctor_bstr(length_error
*this, const basic_string_char
*str
)
457 const char *name
= MSVCP_basic_string_char_c_str(str
);
458 TRACE("(%p %p %s)\n", this, str
, name
);
459 return MSVCP_length_error_ctor(this, EXCEPTION_NAME(name
));
463 /* ??4length_error@std@@QAEAAV01@ABV01@@Z */
464 /* ??4length_error@std@@QEAAAEAV01@AEBV01@@Z */
465 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_assign
, 8)
466 length_error
* __thiscall
MSVCP_length_error_assign(length_error
*this, const length_error
*assign
)
468 MSVCP_logic_error_dtor(this);
469 return MSVCP_length_error_copy_ctor(this, assign
);
472 DEFINE_RTTI_DATA2(length_error
, 0, &logic_error_rtti_base_descriptor
, &exception_rtti_base_descriptor
, ".?AVlength_error@std@@")
473 DEFINE_CXX_DATA2(length_error
, &logic_error_cxx_type_info
, &exception_cxx_type_info
, MSVCP_logic_error_dtor
)
475 /* out_of_range class data */
476 typedef logic_error out_of_range
;
478 static out_of_range
* MSVCP_out_of_range_ctor( out_of_range
*this, exception_name name
)
480 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
481 MSVCP_logic_error_ctor(this, name
);
482 this->e
.vtable
= &MSVCP_out_of_range_vtable
;
486 /* ??0out_of_range@std@@QAE@ABV01@@Z */
487 /* ??0out_of_range@std@@QEAA@AEBV01@@Z */
488 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_copy_ctor
, 8)
489 out_of_range
* __thiscall
MSVCP_out_of_range_copy_ctor(
490 out_of_range
*this, const out_of_range
*rhs
)
492 TRACE("%p %p\n", this, rhs
);
493 MSVCP_logic_error_copy_ctor(this, rhs
);
494 this->e
.vtable
= &MSVCP_out_of_range_vtable
;
498 /* ??0out_of_range@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
499 /* ??0out_of_range@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
501 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_ctor_bstr
, 8)
502 out_of_range
* __thiscall
MSVCP_out_of_range_ctor_bstr(out_of_range
*this, const basic_string_char
*str
)
504 const char *name
= MSVCP_basic_string_char_c_str(str
);
505 TRACE("(%p %p %s)\n", this, str
, name
);
506 return MSVCP_out_of_range_ctor(this, EXCEPTION_NAME(name
));
510 /* ??4out_of_range@std@@QAEAAV01@ABV01@@Z */
511 /* ??4out_of_range@std@@QEAAAEAV01@AEBV01@@Z */
512 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_assign
, 8)
513 out_of_range
* __thiscall
MSVCP_out_of_range_assign(out_of_range
*this, const out_of_range
*assign
)
515 MSVCP_logic_error_dtor(this);
516 return MSVCP_out_of_range_copy_ctor(this, assign
);
519 DEFINE_RTTI_DATA2(out_of_range
, 0, &logic_error_rtti_base_descriptor
, &exception_rtti_base_descriptor
, ".?AVout_of_range@std@@")
520 DEFINE_CXX_DATA2(out_of_range
, &logic_error_cxx_type_info
, &exception_cxx_type_info
, MSVCP_logic_error_dtor
)
522 /* invalid_argument class data */
523 typedef logic_error invalid_argument
;
525 static invalid_argument
* MSVCP_invalid_argument_ctor( invalid_argument
*this, exception_name name
)
527 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
528 MSVCP_logic_error_ctor(this, name
);
529 this->e
.vtable
= &MSVCP_invalid_argument_vtable
;
533 DEFINE_THISCALL_WRAPPER(MSVCP_invalid_argument_copy_ctor
, 8)
534 invalid_argument
* __thiscall
MSVCP_invalid_argument_copy_ctor(
535 invalid_argument
*this, invalid_argument
*rhs
)
537 TRACE("%p %p\n", this, rhs
);
538 MSVCP_logic_error_copy_ctor(this, rhs
);
539 this->e
.vtable
= &MSVCP_invalid_argument_vtable
;
543 DEFINE_RTTI_DATA2(invalid_argument
, 0, &logic_error_rtti_base_descriptor
, &exception_rtti_base_descriptor
, ".?AVinvalid_argument@std@@")
544 DEFINE_CXX_DATA2(invalid_argument
, &logic_error_cxx_type_info
, &exception_cxx_type_info
, MSVCP_logic_error_dtor
)
546 /* runtime_error class data */
549 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
550 basic_string_char str
;
554 static runtime_error
* MSVCP_runtime_error_ctor( runtime_error
*this, exception_name name
)
556 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
557 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
559 MSVCP_exception_ctor(&this->e
, "");
561 MSVCP_exception_ctor(&this->e
, NULL
);
563 MSVCP_basic_string_char_ctor_cstr(&this->str
, EXCEPTION_STR(name
));
565 MSVCP_exception_ctor(&this->e
, name
);
567 this->e
.vtable
= &MSVCP_runtime_error_vtable
;
571 /* ??0runtime_error@std@@QAE@ABV01@@Z */
572 /* ??0runtime_error@std@@QEAA@AEBV01@@Z */
573 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_copy_ctor
, 8)
574 runtime_error
* __thiscall
MSVCP_runtime_error_copy_ctor(
575 runtime_error
*this, const runtime_error
*rhs
)
577 TRACE("%p %p\n", this, rhs
);
578 MSVCP_exception_copy_ctor(&this->e
, &rhs
->e
);
579 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
580 MSVCP_basic_string_char_copy_ctor(&this->str
, &rhs
->str
);
582 this->e
.vtable
= &MSVCP_runtime_error_vtable
;
586 /* ??0runtime_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
587 /* ??0runtime_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
589 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_ctor_bstr
, 8)
590 runtime_error
* __thiscall
MSVCP_runtime_error_ctor_bstr(runtime_error
*this, const basic_string_char
*str
)
592 const char *name
= MSVCP_basic_string_char_c_str(str
);
593 TRACE("(%p %p %s)\n", this, str
, name
);
594 return MSVCP_runtime_error_ctor(this, EXCEPTION_NAME(name
));
598 /* ??1runtime_error@std@@UAE@XZ */
599 /* ??1runtime_error@std@@UEAA@XZ */
600 /* ??1range_error@std@@UAE@XZ */
601 /* ??1range_error@std@@UEAA@XZ */
602 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_dtor
, 4)
603 void __thiscall
MSVCP_runtime_error_dtor(runtime_error
*this)
606 MSVCP_exception_dtor(&this->e
);
607 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
608 MSVCP_basic_string_char_dtor(&this->str
);
612 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_vector_dtor
, 8)
613 void* __thiscall
MSVCP_runtime_error_vector_dtor(
614 runtime_error
*this, unsigned int flags
)
616 TRACE("%p %x\n", this, flags
);
618 /* we have an array, with the number of elements stored before the first object */
619 INT_PTR i
, *ptr
= (INT_PTR
*)this-1;
621 for(i
=*ptr
-1; i
>=0; i
--)
622 MSVCP_runtime_error_dtor(this+i
);
623 MSVCRT_operator_delete(ptr
);
625 MSVCP_runtime_error_dtor(this);
627 MSVCRT_operator_delete(this);
633 /* ??4runtime_error@std@@QAEAAV01@ABV01@@Z */
634 /* ??4runtime_error@std@@QEAAAEAV01@AEBV01@@Z */
635 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_assign
, 8)
636 runtime_error
* __thiscall
MSVCP_runtime_error_assign(runtime_error
*this, const runtime_error
*assign
)
638 MSVCP_runtime_error_dtor(this);
639 return MSVCP_runtime_error_copy_ctor(this, assign
);
642 /* ?what@runtime_error@std@@UBEPBDXZ */
643 /* ?what@runtime_error@std@@UEBAPEBDXZ */
644 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_what
, 4)
645 const char* __thiscall
MSVCP_runtime_error_what(runtime_error
*this)
648 #if _MSVCP_VER > 90 || defined _MSVCIRT
649 return MSVCP_exception_what( &this->e
);
651 return MSVCP_basic_string_char_c_str(&this->str
);
655 DEFINE_RTTI_DATA1(runtime_error
, 0, &exception_rtti_base_descriptor
, ".?AVruntime_error@std@@")
656 DEFINE_CXX_DATA1(runtime_error
, &exception_cxx_type_info
, MSVCP_runtime_error_dtor
)
658 /* failure class data */
659 typedef runtime_error failure
;
661 static failure
* MSVCP_failure_ctor( failure
*this, exception_name name
)
663 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
664 MSVCP_runtime_error_ctor(this, name
);
665 this->e
.vtable
= &MSVCP_failure_vtable
;
669 DEFINE_THISCALL_WRAPPER(MSVCP_failure_copy_ctor
, 8)
670 failure
* __thiscall
MSVCP_failure_copy_ctor(
671 failure
*this, failure
*rhs
)
673 TRACE("%p %p\n", this, rhs
);
674 MSVCP_runtime_error_copy_ctor(this, rhs
);
675 this->e
.vtable
= &MSVCP_failure_vtable
;
679 DEFINE_THISCALL_WRAPPER(MSVCP_failure_dtor
, 4)
680 void __thiscall
MSVCP_failure_dtor(failure
*this)
683 MSVCP_runtime_error_dtor(this);
686 DEFINE_THISCALL_WRAPPER(MSVCP_failure_vector_dtor
, 8)
687 void* __thiscall
MSVCP_failure_vector_dtor(
688 failure
*this, unsigned int flags
)
690 TRACE("%p %x\n", this, flags
);
691 return MSVCP_runtime_error_vector_dtor(this, flags
);
694 DEFINE_THISCALL_WRAPPER(MSVCP_failure_what
, 4)
695 const char* __thiscall
MSVCP_failure_what(failure
*this)
698 return MSVCP_runtime_error_what(this);
701 DEFINE_RTTI_DATA2(failure
, 0, &runtime_error_rtti_base_descriptor
, &exception_rtti_base_descriptor
, ".?AVfailure@std@@")
702 DEFINE_CXX_DATA2(failure
, &runtime_error_cxx_type_info
, &exception_cxx_type_info
, MSVCP_runtime_error_dtor
)
704 /* bad_cast class data */
705 typedef exception bad_cast
;
707 /* ??0bad_cast@std@@QAE@PBD@Z */
708 /* ??0bad_cast@std@@QEAA@PEBD@Z */
709 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_ctor
, 8)
710 bad_cast
* __thiscall
MSVCP_bad_cast_ctor(bad_cast
*this, const char *name
)
712 TRACE("%p %s\n", this, name
);
713 MSVCP_exception_ctor(this, EXCEPTION_NAME(name
));
714 this->vtable
= &MSVCP_bad_cast_vtable
;
718 /* ??_Fbad_cast@@QAEXXZ */
719 /* ??_Fbad_cast@std@@QEAAXXZ */
720 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_default_ctor
,4)
721 bad_cast
* __thiscall
MSVCP_bad_cast_default_ctor(bad_cast
*this)
723 return MSVCP_bad_cast_ctor(this, "bad cast");
726 /* ??0bad_cast@std@@QAE@ABV01@@Z */
727 /* ??0bad_cast@std@@QEAA@AEBV01@@Z */
728 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_copy_ctor
, 8)
729 bad_cast
* __thiscall
MSVCP_bad_cast_copy_ctor(bad_cast
*this, const bad_cast
*rhs
)
731 TRACE("%p %p\n", this, rhs
);
732 MSVCP_exception_copy_ctor(this, rhs
);
733 this->vtable
= &MSVCP_bad_cast_vtable
;
737 /* ??1bad_cast@@UAE@XZ */
738 /* ??1bad_cast@std@@UEAA@XZ */
739 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_dtor
, 4)
740 void __thiscall
MSVCP_bad_cast_dtor(bad_cast
*this)
743 MSVCP_exception_dtor(this);
746 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_vector_dtor
, 8)
747 void * __thiscall
MSVCP_bad_cast_vector_dtor(bad_cast
*this, unsigned int flags
)
749 TRACE("%p %x\n", this, flags
);
751 /* we have an array, with the number of elements stored before the first object */
752 INT_PTR i
, *ptr
= (INT_PTR
*)this-1;
754 for(i
=*ptr
-1; i
>=0; i
--)
755 MSVCP_bad_cast_dtor(this+i
);
756 MSVCRT_operator_delete(ptr
);
758 MSVCP_bad_cast_dtor(this);
760 MSVCRT_operator_delete(this);
766 /* ??4bad_cast@std@@QAEAAV01@ABV01@@Z */
767 /* ??4bad_cast@std@@QEAAAEAV01@AEBV01@@Z */
768 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_opequals
, 8)
769 bad_cast
* __thiscall
MSVCP_bad_cast_opequals(bad_cast
*this, const bad_cast
*rhs
)
771 TRACE("(%p %p)\n", this, rhs
);
774 MSVCP_exception_dtor(this);
775 MSVCP_exception_copy_ctor(this, rhs
);
780 DEFINE_RTTI_DATA1(bad_cast
, 0, &exception_rtti_base_descriptor
, ".?AVbad_cast@std@@")
781 DEFINE_CXX_DATA1(bad_cast
, &exception_cxx_type_info
, MSVCP_bad_cast_dtor
)
783 /* range_error class data */
784 typedef runtime_error range_error
;
786 static range_error
* MSVCP_range_error_ctor( range_error
*this, exception_name name
)
788 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
789 MSVCP_runtime_error_ctor(this, name
);
790 this->e
.vtable
= &MSVCP_range_error_vtable
;
794 /* ??0range_error@std@@QAE@ABV01@@Z */
795 /* ??0range_error@std@@QEAA@AEBV01@@Z */
796 DEFINE_THISCALL_WRAPPER(MSVCP_range_error_copy_ctor
, 8)
797 range_error
* __thiscall
MSVCP_range_error_copy_ctor(
798 range_error
*this, const range_error
*rhs
)
800 TRACE("%p %p\n", this, rhs
);
801 MSVCP_runtime_error_copy_ctor(this, rhs
);
802 this->e
.vtable
= &MSVCP_range_error_vtable
;
806 /* ??0range_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
807 /* ??0range_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
809 DEFINE_THISCALL_WRAPPER(MSVCP_range_error_ctor_bstr
, 8)
810 range_error
* __thiscall
MSVCP_range_error_ctor_bstr(range_error
*this, const basic_string_char
*str
)
812 const char *name
= MSVCP_basic_string_char_c_str(str
);
813 TRACE("(%p %p %s)\n", this, str
, name
);
814 return MSVCP_range_error_ctor(this, EXCEPTION_NAME(name
));
818 /* ??4range_error@std@@QAEAAV01@ABV01@@Z */
819 /* ??4range_error@std@@QEAAAEAV01@AEBV01@@Z */
820 DEFINE_THISCALL_WRAPPER(MSVCP_range_error_assign
, 8)
821 range_error
* __thiscall
MSVCP_range_error_assign(range_error
*this, const range_error
*assign
)
823 MSVCP_runtime_error_dtor(this);
824 return MSVCP_range_error_copy_ctor(this, assign
);
827 DEFINE_RTTI_DATA2(range_error
, 0, &runtime_error_rtti_base_descriptor
, &exception_rtti_base_descriptor
, ".?AVrange_error@std@@")
828 DEFINE_CXX_DATA2(range_error
, &runtime_error_cxx_type_info
, &exception_cxx_type_info
, MSVCP_runtime_error_dtor
)
830 /* ?_Nomemory@std@@YAXXZ */
831 void __cdecl
_Nomemory(void)
834 throw_exception(EXCEPTION_BAD_ALLOC
, NULL
);
837 /* ?_Xmem@tr1@std@@YAXXZ */
838 void __cdecl
_Xmem(void)
841 throw_exception(EXCEPTION_BAD_ALLOC
, NULL
);
844 /* ?_Xinvalid_argument@std@@YAXPBD@Z */
845 /* ?_Xinvalid_argument@std@@YAXPEBD@Z */
846 void __cdecl
_Xinvalid_argument(const char *str
)
848 TRACE("(%s)\n", debugstr_a(str
));
849 throw_exception(EXCEPTION_INVALID_ARGUMENT
, str
);
852 /* ?_Xlength_error@std@@YAXPBD@Z */
853 /* ?_Xlength_error@std@@YAXPEBD@Z */
854 void __cdecl
_Xlength_error(const char *str
)
856 TRACE("(%s)\n", debugstr_a(str
));
857 throw_exception(EXCEPTION_LENGTH_ERROR
, str
);
860 /* ?_Xout_of_range@std@@YAXPBD@Z */
861 /* ?_Xout_of_range@std@@YAXPEBD@Z */
862 void __cdecl
_Xout_of_range(const char *str
)
864 TRACE("(%s)\n", debugstr_a(str
));
865 throw_exception(EXCEPTION_OUT_OF_RANGE
, str
);
868 /* ?_Xruntime_error@std@@YAXPBD@Z */
869 /* ?_Xruntime_error@std@@YAXPEBD@Z */
870 void __cdecl
_Xruntime_error(const char *str
)
872 TRACE("(%s)\n", debugstr_a(str
));
873 throw_exception(EXCEPTION_RUNTIME_ERROR
, str
);
876 /* ?uncaught_exception@std@@YA_NXZ */
877 MSVCP_bool __cdecl
MSVCP__uncaught_exception(void)
879 return __uncaught_exception();
882 #if _MSVCP_VER >= 70 || defined(_MSVCIRT)
883 #define EXCEPTION_VTABLE(name,funcs) __ASM_VTABLE(name,funcs)
885 #define EXCEPTION_VTABLE(name,funcs) __ASM_VTABLE(name,funcs VTABLE_ADD_FUNC(MSVCP_exception__Doraise))
889 void __asm_dummy_vtables(void) {
891 __ASM_VTABLE(type_info
,
892 VTABLE_ADD_FUNC(MSVCP_type_info_vector_dtor
));
893 EXCEPTION_VTABLE(exception
,
894 VTABLE_ADD_FUNC(MSVCP_exception_vector_dtor
)
895 VTABLE_ADD_FUNC(MSVCP_exception_what
));
896 EXCEPTION_VTABLE(bad_alloc
,
897 VTABLE_ADD_FUNC(MSVCP_bad_alloc_vector_dtor
)
898 VTABLE_ADD_FUNC(MSVCP_exception_what
));
899 EXCEPTION_VTABLE(logic_error
,
900 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor
)
901 VTABLE_ADD_FUNC(MSVCP_logic_error_what
));
902 EXCEPTION_VTABLE(length_error
,
903 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor
)
904 VTABLE_ADD_FUNC(MSVCP_logic_error_what
));
905 EXCEPTION_VTABLE(out_of_range
,
906 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor
)
907 VTABLE_ADD_FUNC(MSVCP_logic_error_what
));
908 EXCEPTION_VTABLE(invalid_argument
,
909 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor
)
910 VTABLE_ADD_FUNC(MSVCP_logic_error_what
));
911 EXCEPTION_VTABLE(runtime_error
,
912 VTABLE_ADD_FUNC(MSVCP_runtime_error_vector_dtor
)
913 VTABLE_ADD_FUNC(MSVCP_runtime_error_what
));
914 EXCEPTION_VTABLE(failure
,
915 VTABLE_ADD_FUNC(MSVCP_failure_vector_dtor
)
916 VTABLE_ADD_FUNC(MSVCP_failure_what
));
917 EXCEPTION_VTABLE(bad_cast
,
918 VTABLE_ADD_FUNC(MSVCP_bad_cast_vector_dtor
)
919 VTABLE_ADD_FUNC(MSVCP_exception_what
));
920 EXCEPTION_VTABLE(range_error
,
921 VTABLE_ADD_FUNC(MSVCP_runtime_error_vector_dtor
)
922 VTABLE_ADD_FUNC(MSVCP_runtime_error_what
));
927 /* Internal: throws selected exception */
928 void throw_exception(exception_type et
, const char *str
)
930 exception_name name
= EXCEPTION_NAME(str
);
933 case EXCEPTION_RERAISE
:
934 _CxxThrowException(NULL
, NULL
);
937 MSVCP_exception_ctor(&e
, name
);
938 _CxxThrowException(&e
, &exception_cxx_type
);
940 case EXCEPTION_BAD_ALLOC
: {
942 MSVCP_bad_alloc_ctor(&e
, name
);
943 _CxxThrowException(&e
, &bad_alloc_cxx_type
);
945 case EXCEPTION_BAD_CAST
: {
947 MSVCP_bad_cast_ctor(&e
, str
);
948 _CxxThrowException(&e
, &bad_cast_cxx_type
);
950 case EXCEPTION_LOGIC_ERROR
: {
952 MSVCP_logic_error_ctor(&e
, name
);
953 _CxxThrowException((exception
*)&e
, &logic_error_cxx_type
);
955 case EXCEPTION_LENGTH_ERROR
: {
957 MSVCP_length_error_ctor(&e
, name
);
958 _CxxThrowException((exception
*)&e
, &length_error_cxx_type
);
960 case EXCEPTION_OUT_OF_RANGE
: {
962 MSVCP_out_of_range_ctor(&e
, name
);
963 _CxxThrowException((exception
*)&e
, &out_of_range_cxx_type
);
965 case EXCEPTION_INVALID_ARGUMENT
: {
967 MSVCP_invalid_argument_ctor(&e
, name
);
968 _CxxThrowException((exception
*)&e
, &invalid_argument_cxx_type
);
970 case EXCEPTION_RUNTIME_ERROR
: {
972 MSVCP_runtime_error_ctor(&e
, name
);
973 _CxxThrowException((exception
*)&e
, &runtime_error_cxx_type
);
975 case EXCEPTION_FAILURE
: {
977 MSVCP_failure_ctor(&e
, name
);
978 _CxxThrowException((exception
*)&e
, &failure_cxx_type
);
980 case EXCEPTION_RANGE_ERROR
: {
982 MSVCP_range_error_ctor(&e
, name
);
983 _CxxThrowException((exception
*)&e
, &range_error_cxx_type
);
988 void init_exception(void *base
)
991 init_type_info_rtti(base
);
992 init_exception_rtti(base
);
993 init_bad_alloc_rtti(base
);
994 init_logic_error_rtti(base
);
995 init_length_error_rtti(base
);
996 init_out_of_range_rtti(base
);
997 init_invalid_argument_rtti(base
);
998 init_runtime_error_rtti(base
);
999 init_failure_rtti(base
);
1000 init_bad_cast_rtti(base
);
1001 init_range_error_rtti(base
);
1003 init_exception_cxx(base
);
1004 init_bad_alloc_cxx(base
);
1005 init_logic_error_cxx(base
);
1006 init_length_error_cxx(base
);
1007 init_out_of_range_cxx(base
);
1008 init_invalid_argument_cxx(base
);
1009 init_runtime_error_cxx(base
);
1010 init_failure_cxx(base
);
1011 init_bad_cast_cxx(base
);
1012 init_range_error_cxx(base
);