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__System_error_vtable
;
60 extern const vtable_ptr MSVCP_system_error_vtable
;
61 extern const vtable_ptr MSVCP_failure_vtable
;
62 /* ??_7bad_cast@std@@6B@ */
63 extern const vtable_ptr MSVCP_bad_cast_vtable
;
64 /* ??_7range_error@std@@6B@ */
65 extern const vtable_ptr MSVCP_range_error_vtable
;
67 static void MSVCP_type_info_dtor(type_info
* _this
)
73 DEFINE_THISCALL_WRAPPER(MSVCP_type_info_vector_dtor
,8)
74 void * __thiscall
MSVCP_type_info_vector_dtor(type_info
* _this
, unsigned int flags
)
76 TRACE("(%p %x)\n", _this
, flags
);
79 /* we have an array, with the number of elements stored before the first object */
80 INT_PTR i
, *ptr
= (INT_PTR
*)_this
- 1;
82 for (i
= *ptr
- 1; i
>= 0; i
--) MSVCP_type_info_dtor(_this
+ i
);
83 MSVCRT_operator_delete(ptr
);
87 MSVCP_type_info_dtor(_this
);
88 if (flags
& 1) MSVCRT_operator_delete(_this
);
93 DEFINE_RTTI_DATA0( type_info
, 0, ".?AVtype_info@@" )
95 /* ??0exception@@QAE@ABQBD@Z */
96 /* ??0exception@@QEAA@AEBQEBD@Z */
97 DEFINE_THISCALL_WRAPPER(MSVCP_exception_ctor
,8)
98 exception
* __thiscall
MSVCP_exception_ctor(exception
*this, exception_name name
)
100 TRACE("(%p %s)\n", this, EXCEPTION_STR(name
));
102 this->vtable
= &MSVCP_exception_vtable
;
103 if(EXCEPTION_STR(name
)) {
104 unsigned int name_len
= strlen(EXCEPTION_STR(name
)) + 1;
105 this->name
= malloc(name_len
);
106 memcpy(this->name
, EXCEPTION_STR(name
), name_len
);
107 this->do_free
= TRUE
;
110 this->do_free
= FALSE
;
115 DEFINE_THISCALL_WRAPPER(MSVCP_exception_copy_ctor
,8)
116 exception
* __thiscall
MSVCP_exception_copy_ctor(exception
*this, const exception
*rhs
)
118 TRACE("(%p,%p)\n", this, rhs
);
121 this->vtable
= &MSVCP_exception_vtable
;
122 this->name
= rhs
->name
;
123 this->do_free
= FALSE
;
125 MSVCP_exception_ctor(this, EXCEPTION_NAME(rhs
->name
));
126 TRACE("name = %s\n", this->name
);
130 /* ??0exception@@QAE@XZ */
131 /* ??0exception@@QEAA@XZ */
132 DEFINE_THISCALL_WRAPPER(MSVCP_exception_default_ctor
,4)
133 exception
* __thiscall
MSVCP_exception_default_ctor(exception
*this)
135 TRACE("(%p)\n", this);
136 this->vtable
= &MSVCP_exception_vtable
;
138 this->do_free
= FALSE
;
142 DEFINE_THISCALL_WRAPPER(MSVCP_exception_dtor
,4)
143 void __thiscall
MSVCP_exception_dtor(exception
*this)
145 TRACE("(%p)\n", this);
146 this->vtable
= &MSVCP_exception_vtable
;
151 DEFINE_THISCALL_WRAPPER(MSVCP_exception_vector_dtor
, 8)
152 void * __thiscall
MSVCP_exception_vector_dtor(exception
*this, unsigned int flags
)
154 TRACE("%p %x\n", this, flags
);
156 /* we have an array, with the number of elements stored before the first object */
157 INT_PTR i
, *ptr
= (INT_PTR
*)this-1;
159 for(i
=*ptr
-1; i
>=0; i
--)
160 MSVCP_exception_dtor(this+i
);
161 MSVCRT_operator_delete(ptr
);
163 MSVCP_exception_dtor(this);
165 MSVCRT_operator_delete(this);
171 /* ??_Gexception@@UAEPAXI@Z */
172 DEFINE_THISCALL_WRAPPER(MSVCP_exception_scalar_dtor
, 8)
173 void * __thiscall
MSVCP_exception_scalar_dtor(exception
*this, unsigned int flags
)
175 TRACE("(%p %x)\n", this, flags
);
176 MSVCP_exception_dtor(this);
177 if (flags
& 1) MSVCRT_operator_delete(this);
181 /* ??4exception@@QAEAAV0@ABV0@@Z */
182 /* ??4exception@@QEAAAEAV0@AEBV0@@Z */
183 DEFINE_THISCALL_WRAPPER(MSVCP_exception_assign
, 8)
184 exception
* __thiscall
MSVCP_exception_assign(exception
*this, const exception
*assign
)
186 MSVCP_exception_dtor(this);
187 return MSVCP_exception_copy_ctor(this, assign
);
190 /* ?_Doraise@bad_alloc@std@@MBEXXZ */
191 /* ?_Doraise@bad_alloc@std@@MEBAXXZ */
192 /* ?_Doraise@logic_error@std@@MBEXXZ */
193 /* ?_Doraise@logic_error@std@@MEBAXXZ */
194 /* ?_Doraise@length_error@std@@MBEXXZ */
195 /* ?_Doraise@length_error@std@@MEBAXXZ */
196 /* ?_Doraise@out_of_range@std@@MBEXXZ */
197 /* ?_Doraise@out_of_range@std@@MEBAXXZ */
198 /* ?_Doraise@runtime_error@std@@MBEXXZ */
199 /* ?_Doraise@runtime_error@std@@MEBAXXZ */
200 /* ?_Doraise@bad_cast@std@@MBEXXZ */
201 /* ?_Doraise@bad_cast@std@@MEBAXXZ */
202 /* ?_Doraise@range_error@std@@MBEXXZ */
203 /* ?_Doraise@range_error@std@@MEBAXXZ */
204 DEFINE_THISCALL_WRAPPER(MSVCP_exception__Doraise
, 4)
205 void __thiscall
MSVCP_exception__Doraise(exception
*this)
207 FIXME("(%p) stub\n", this);
210 DEFINE_THISCALL_WRAPPER(MSVCP_exception_what
,4)
211 const char* __thiscall
MSVCP_exception_what(exception
* this)
213 TRACE("(%p) returning %s\n", this, this->name
);
214 return this->name
? this->name
: "Unknown exception";
218 DEFINE_RTTI_DATA0(exception
, 0, ".?AVexception@std@@")
220 DEFINE_RTTI_DATA0(exception
, 0, ".?AVexception@@")
222 DEFINE_CXX_DATA0(exception
, MSVCP_exception_dtor
)
224 /* bad_alloc class data */
225 typedef exception bad_alloc
;
227 /* ??0bad_alloc@std@@QAE@PBD@Z */
228 /* ??0bad_alloc@std@@QEAA@PEBD@Z */
229 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_ctor
, 8)
230 bad_alloc
* __thiscall
MSVCP_bad_alloc_ctor(bad_alloc
*this, exception_name name
)
232 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
233 MSVCP_exception_ctor(this, name
);
234 this->vtable
= &MSVCP_bad_alloc_vtable
;
238 /* ??0bad_alloc@std@@QAE@XZ */
239 /* ??0bad_alloc@std@@QEAA@XZ */
240 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_default_ctor
, 4)
241 bad_alloc
* __thiscall
MSVCP_bad_alloc_default_ctor(bad_alloc
*this)
243 static const char name
[] = "bad allocation";
244 return MSVCP_bad_alloc_ctor(this, EXCEPTION_NAME(name
));
247 /* ??0bad_alloc@std@@QAE@ABV01@@Z */
248 /* ??0bad_alloc@std@@QEAA@AEBV01@@Z */
249 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_copy_ctor
, 8)
250 bad_alloc
* __thiscall
MSVCP_bad_alloc_copy_ctor(bad_alloc
*this, const bad_alloc
*rhs
)
252 TRACE("%p %p\n", this, rhs
);
253 MSVCP_exception_copy_ctor(this, rhs
);
254 this->vtable
= &MSVCP_bad_alloc_vtable
;
258 /* ??1bad_alloc@std@@UAE@XZ */
259 /* ??1bad_alloc@std@@UEAA@XZ */
260 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_dtor
, 4)
261 void __thiscall
MSVCP_bad_alloc_dtor(bad_alloc
*this)
264 MSVCP_exception_dtor(this);
267 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_vector_dtor
, 8)
268 void * __thiscall
MSVCP_bad_alloc_vector_dtor(bad_alloc
*this, unsigned int flags
)
270 TRACE("%p %x\n", this, flags
);
272 /* we have an array, with the number of elements stored before the first object */
273 INT_PTR i
, *ptr
= (INT_PTR
*)this-1;
275 for(i
=*ptr
-1; i
>=0; i
--)
276 MSVCP_bad_alloc_dtor(this+i
);
277 MSVCRT_operator_delete(ptr
);
279 MSVCP_bad_alloc_dtor(this);
281 MSVCRT_operator_delete(this);
287 /* ??4bad_alloc@std@@QAEAAV01@ABV01@@Z */
288 /* ??4bad_alloc@std@@QEAAAEAV01@AEBV01@@Z */
289 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_assign
, 8)
290 bad_alloc
* __thiscall
MSVCP_bad_alloc_assign(bad_alloc
*this, const bad_alloc
*assign
)
292 MSVCP_bad_alloc_dtor(this);
293 return MSVCP_bad_alloc_copy_ctor(this, assign
);
296 DEFINE_RTTI_DATA1(bad_alloc
, 0, &exception_rtti_base_descriptor
, ".?AVbad_alloc@std@@")
297 DEFINE_CXX_DATA1(bad_alloc
, &exception_cxx_type_info
, MSVCP_bad_alloc_dtor
)
299 /* logic_error class data */
302 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
303 basic_string_char str
;
307 /* ??0logic_error@@QAE@ABQBD@Z */
308 /* ??0logic_error@@QEAA@AEBQEBD@Z */
309 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_ctor
, 8)
310 logic_error
* __thiscall
MSVCP_logic_error_ctor( logic_error
*this, exception_name name
)
312 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
313 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
315 MSVCP_exception_ctor(&this->e
, "");
317 MSVCP_exception_ctor(&this->e
, NULL
);
319 MSVCP_basic_string_char_ctor_cstr(&this->str
, EXCEPTION_STR(name
));
321 MSVCP_exception_ctor(&this->e
, name
);
323 this->e
.vtable
= &MSVCP_logic_error_vtable
;
327 /* ??0logic_error@std@@QAE@ABV01@@Z */
328 /* ??0logic_error@std@@QEAA@AEBV01@@Z */
329 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_copy_ctor
, 8)
330 logic_error
* __thiscall
MSVCP_logic_error_copy_ctor(
331 logic_error
*this, const logic_error
*rhs
)
333 TRACE("%p %p\n", this, rhs
);
334 MSVCP_exception_copy_ctor(&this->e
, &rhs
->e
);
335 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
336 MSVCP_basic_string_char_copy_ctor(&this->str
, &rhs
->str
);
338 this->e
.vtable
= &MSVCP_logic_error_vtable
;
342 /* ??0logic_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
343 /* ??0logic_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
345 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_ctor_bstr
, 8)
346 logic_error
* __thiscall
MSVCP_logic_error_ctor_bstr(logic_error
*this, const basic_string_char
*str
)
348 const char *name
= MSVCP_basic_string_char_c_str(str
);
349 TRACE("(%p %p %s)\n", this, str
, name
);
350 return MSVCP_logic_error_ctor(this, EXCEPTION_NAME(name
));
354 /* ??1logic_error@std@@UAE@XZ */
355 /* ??1logic_error@std@@UEAA@XZ */
356 /* ??1length_error@std@@UAE@XZ */
357 /* ??1length_error@std@@UEAA@XZ */
358 /* ??1out_of_range@std@@UAE@XZ */
359 /* ??1out_of_range@std@@UEAA@XZ */
360 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_dtor
, 4)
361 void __thiscall
MSVCP_logic_error_dtor(logic_error
*this)
364 MSVCP_exception_dtor(&this->e
);
365 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
366 MSVCP_basic_string_char_dtor(&this->str
);
370 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_vector_dtor
, 8)
371 void* __thiscall
MSVCP_logic_error_vector_dtor(
372 logic_error
*this, unsigned int flags
)
374 TRACE("%p %x\n", this, flags
);
376 /* we have an array, with the number of elements stored before the first object */
377 INT_PTR i
, *ptr
= (INT_PTR
*)this-1;
379 for(i
=*ptr
-1; i
>=0; i
--)
380 MSVCP_logic_error_dtor(this+i
);
381 MSVCRT_operator_delete(ptr
);
383 MSVCP_logic_error_dtor(this);
385 MSVCRT_operator_delete(this);
391 /* ??_Glogic_error@@UAEPAXI@Z */
392 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_scalar_dtor
, 8)
393 void * __thiscall
MSVCP_logic_error_scalar_dtor(logic_error
*this, unsigned int flags
)
395 TRACE("(%p %x)\n", this, flags
);
396 MSVCP_logic_error_dtor(this);
397 if (flags
& 1) MSVCRT_operator_delete(this);
401 /* ??4logic_error@std@@QAEAAV01@ABV01@@Z */
402 /* ??4logic_error@std@@QEAAAEAV01@AEBV01@@Z */
403 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_assign
, 8)
404 logic_error
* __thiscall
MSVCP_logic_error_assign(logic_error
*this, const logic_error
*assign
)
406 MSVCP_logic_error_dtor(this);
407 return MSVCP_logic_error_copy_ctor(this, assign
);
410 /* ?what@logic_error@std@@UBEPBDXZ */
411 /* ?what@logic_error@std@@UEBAPEBDXZ */
412 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_what
, 4)
413 const char* __thiscall
MSVCP_logic_error_what(logic_error
*this)
416 #if _MSVCP_VER > 90 || defined _MSVCIRT
417 return MSVCP_exception_what( &this->e
);
419 return MSVCP_basic_string_char_c_str(&this->str
);
424 DEFINE_RTTI_DATA1(logic_error
, 0, &exception_rtti_base_descriptor
, ".?AVlogic_error@std@@")
426 DEFINE_RTTI_DATA1(logic_error
, 0, &exception_rtti_base_descriptor
, ".?AVlogic_error@@")
428 DEFINE_CXX_DATA1(logic_error
, &exception_cxx_type_info
, MSVCP_logic_error_dtor
)
430 /* length_error class data */
431 typedef logic_error length_error
;
433 static length_error
* MSVCP_length_error_ctor( length_error
*this, exception_name name
)
435 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
436 MSVCP_logic_error_ctor(this, name
);
437 this->e
.vtable
= &MSVCP_length_error_vtable
;
441 /* ??0length_error@std@@QAE@ABV01@@Z */
442 /* ??0length_error@std@@QEAA@AEBV01@@Z */
443 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_copy_ctor
, 8)
444 length_error
* __thiscall
MSVCP_length_error_copy_ctor(
445 length_error
*this, const length_error
*rhs
)
447 TRACE("%p %p\n", this, rhs
);
448 MSVCP_logic_error_copy_ctor(this, rhs
);
449 this->e
.vtable
= &MSVCP_length_error_vtable
;
453 /* ??0length_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
454 /* ??0length_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
456 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_ctor_bstr
, 8)
457 length_error
* __thiscall
MSVCP_length_error_ctor_bstr(length_error
*this, const basic_string_char
*str
)
459 const char *name
= MSVCP_basic_string_char_c_str(str
);
460 TRACE("(%p %p %s)\n", this, str
, name
);
461 return MSVCP_length_error_ctor(this, EXCEPTION_NAME(name
));
465 /* ??4length_error@std@@QAEAAV01@ABV01@@Z */
466 /* ??4length_error@std@@QEAAAEAV01@AEBV01@@Z */
467 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_assign
, 8)
468 length_error
* __thiscall
MSVCP_length_error_assign(length_error
*this, const length_error
*assign
)
470 MSVCP_logic_error_dtor(this);
471 return MSVCP_length_error_copy_ctor(this, assign
);
474 DEFINE_RTTI_DATA2(length_error
, 0, &logic_error_rtti_base_descriptor
, &exception_rtti_base_descriptor
, ".?AVlength_error@std@@")
475 DEFINE_CXX_DATA2(length_error
, &logic_error_cxx_type_info
, &exception_cxx_type_info
, MSVCP_logic_error_dtor
)
477 /* out_of_range class data */
478 typedef logic_error out_of_range
;
480 static out_of_range
* MSVCP_out_of_range_ctor( out_of_range
*this, exception_name name
)
482 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
483 MSVCP_logic_error_ctor(this, name
);
484 this->e
.vtable
= &MSVCP_out_of_range_vtable
;
488 /* ??0out_of_range@std@@QAE@ABV01@@Z */
489 /* ??0out_of_range@std@@QEAA@AEBV01@@Z */
490 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_copy_ctor
, 8)
491 out_of_range
* __thiscall
MSVCP_out_of_range_copy_ctor(
492 out_of_range
*this, const out_of_range
*rhs
)
494 TRACE("%p %p\n", this, rhs
);
495 MSVCP_logic_error_copy_ctor(this, rhs
);
496 this->e
.vtable
= &MSVCP_out_of_range_vtable
;
500 /* ??0out_of_range@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
501 /* ??0out_of_range@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
503 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_ctor_bstr
, 8)
504 out_of_range
* __thiscall
MSVCP_out_of_range_ctor_bstr(out_of_range
*this, const basic_string_char
*str
)
506 const char *name
= MSVCP_basic_string_char_c_str(str
);
507 TRACE("(%p %p %s)\n", this, str
, name
);
508 return MSVCP_out_of_range_ctor(this, EXCEPTION_NAME(name
));
512 /* ??4out_of_range@std@@QAEAAV01@ABV01@@Z */
513 /* ??4out_of_range@std@@QEAAAEAV01@AEBV01@@Z */
514 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_assign
, 8)
515 out_of_range
* __thiscall
MSVCP_out_of_range_assign(out_of_range
*this, const out_of_range
*assign
)
517 MSVCP_logic_error_dtor(this);
518 return MSVCP_out_of_range_copy_ctor(this, assign
);
521 DEFINE_RTTI_DATA2(out_of_range
, 0, &logic_error_rtti_base_descriptor
, &exception_rtti_base_descriptor
, ".?AVout_of_range@std@@")
522 DEFINE_CXX_DATA2(out_of_range
, &logic_error_cxx_type_info
, &exception_cxx_type_info
, MSVCP_logic_error_dtor
)
524 /* invalid_argument class data */
525 typedef logic_error invalid_argument
;
527 static invalid_argument
* MSVCP_invalid_argument_ctor( invalid_argument
*this, exception_name name
)
529 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
530 MSVCP_logic_error_ctor(this, name
);
531 this->e
.vtable
= &MSVCP_invalid_argument_vtable
;
535 DEFINE_THISCALL_WRAPPER(MSVCP_invalid_argument_copy_ctor
, 8)
536 invalid_argument
* __thiscall
MSVCP_invalid_argument_copy_ctor(
537 invalid_argument
*this, invalid_argument
*rhs
)
539 TRACE("%p %p\n", this, rhs
);
540 MSVCP_logic_error_copy_ctor(this, rhs
);
541 this->e
.vtable
= &MSVCP_invalid_argument_vtable
;
545 DEFINE_RTTI_DATA2(invalid_argument
, 0, &logic_error_rtti_base_descriptor
, &exception_rtti_base_descriptor
, ".?AVinvalid_argument@std@@")
546 DEFINE_CXX_DATA2(invalid_argument
, &logic_error_cxx_type_info
, &exception_cxx_type_info
, MSVCP_logic_error_dtor
)
548 /* runtime_error class data */
551 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
552 basic_string_char str
;
556 static runtime_error
* MSVCP_runtime_error_ctor( runtime_error
*this, exception_name name
)
558 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
559 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
561 MSVCP_exception_ctor(&this->e
, "");
563 MSVCP_exception_ctor(&this->e
, NULL
);
565 MSVCP_basic_string_char_ctor_cstr(&this->str
, EXCEPTION_STR(name
));
567 MSVCP_exception_ctor(&this->e
, name
);
569 this->e
.vtable
= &MSVCP_runtime_error_vtable
;
573 /* ??0runtime_error@std@@QAE@ABV01@@Z */
574 /* ??0runtime_error@std@@QEAA@AEBV01@@Z */
575 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_copy_ctor
, 8)
576 runtime_error
* __thiscall
MSVCP_runtime_error_copy_ctor(
577 runtime_error
*this, const runtime_error
*rhs
)
579 TRACE("%p %p\n", this, rhs
);
580 MSVCP_exception_copy_ctor(&this->e
, &rhs
->e
);
581 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
582 MSVCP_basic_string_char_copy_ctor(&this->str
, &rhs
->str
);
584 this->e
.vtable
= &MSVCP_runtime_error_vtable
;
588 /* ??0runtime_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
589 /* ??0runtime_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
591 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_ctor_bstr
, 8)
592 runtime_error
* __thiscall
MSVCP_runtime_error_ctor_bstr(runtime_error
*this, const basic_string_char
*str
)
594 const char *name
= MSVCP_basic_string_char_c_str(str
);
595 TRACE("(%p %p %s)\n", this, str
, name
);
596 return MSVCP_runtime_error_ctor(this, EXCEPTION_NAME(name
));
600 /* ??1runtime_error@std@@UAE@XZ */
601 /* ??1runtime_error@std@@UEAA@XZ */
602 /* ??1range_error@std@@UAE@XZ */
603 /* ??1range_error@std@@UEAA@XZ */
604 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_dtor
, 4)
605 void __thiscall
MSVCP_runtime_error_dtor(runtime_error
*this)
608 MSVCP_exception_dtor(&this->e
);
609 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
610 MSVCP_basic_string_char_dtor(&this->str
);
614 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_vector_dtor
, 8)
615 void* __thiscall
MSVCP_runtime_error_vector_dtor(
616 runtime_error
*this, unsigned int flags
)
618 TRACE("%p %x\n", this, flags
);
620 /* we have an array, with the number of elements stored before the first object */
621 INT_PTR i
, *ptr
= (INT_PTR
*)this-1;
623 for(i
=*ptr
-1; i
>=0; i
--)
624 MSVCP_runtime_error_dtor(this+i
);
625 MSVCRT_operator_delete(ptr
);
627 MSVCP_runtime_error_dtor(this);
629 MSVCRT_operator_delete(this);
635 /* ??4runtime_error@std@@QAEAAV01@ABV01@@Z */
636 /* ??4runtime_error@std@@QEAAAEAV01@AEBV01@@Z */
637 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_assign
, 8)
638 runtime_error
* __thiscall
MSVCP_runtime_error_assign(runtime_error
*this, const runtime_error
*assign
)
640 MSVCP_runtime_error_dtor(this);
641 return MSVCP_runtime_error_copy_ctor(this, assign
);
644 /* ?what@runtime_error@std@@UBEPBDXZ */
645 /* ?what@runtime_error@std@@UEBAPEBDXZ */
646 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_what
, 4)
647 const char* __thiscall
MSVCP_runtime_error_what(runtime_error
*this)
650 #if _MSVCP_VER > 90 || defined _MSVCIRT
651 return MSVCP_exception_what( &this->e
);
653 return MSVCP_basic_string_char_c_str(&this->str
);
657 DEFINE_RTTI_DATA1(runtime_error
, 0, &exception_rtti_base_descriptor
, ".?AVruntime_error@std@@")
658 DEFINE_CXX_DATA1(runtime_error
, &exception_cxx_type_info
, MSVCP_runtime_error_dtor
)
660 /* failure class data */
667 typedef system_error _System_error
;
668 typedef system_error failure
;
670 static failure
* MSVCP_failure_ctor( failure
*this, exception_name name
)
672 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
673 MSVCP_runtime_error_ctor(&this->base
, name
);
675 /* FIXME: set err correctly */
678 this->base
.e
.vtable
= &MSVCP_failure_vtable
;
682 DEFINE_THISCALL_WRAPPER(MSVCP_failure_copy_ctor
, 8)
683 failure
* __thiscall
MSVCP_failure_copy_ctor(
684 failure
*this, failure
*rhs
)
686 TRACE("%p %p\n", this, rhs
);
687 MSVCP_runtime_error_copy_ctor(&this->base
, &rhs
->base
);
689 this->err
= rhs
->err
;
691 this->base
.e
.vtable
= &MSVCP_failure_vtable
;
695 DEFINE_THISCALL_WRAPPER(MSVCP_failure_dtor
, 4)
696 void __thiscall
MSVCP_failure_dtor(failure
*this)
699 MSVCP_runtime_error_dtor(&this->base
);
702 DEFINE_THISCALL_WRAPPER(MSVCP_failure_vector_dtor
, 8)
703 void* __thiscall
MSVCP_failure_vector_dtor(
704 failure
*this, unsigned int flags
)
706 TRACE("%p %x\n", this, flags
);
707 return MSVCP_runtime_error_vector_dtor(&this->base
, flags
);
710 DEFINE_THISCALL_WRAPPER(MSVCP_failure_what
, 4)
711 const char* __thiscall
MSVCP_failure_what(failure
*this)
714 return MSVCP_runtime_error_what(&this->base
);
718 DEFINE_THISCALL_WRAPPER(MSVCP_system_error_copy_ctor
, 8)
719 system_error
* __thiscall
MSVCP_system_error_copy_ctor(
720 system_error
*this, system_error
*rhs
)
722 MSVCP_failure_copy_ctor(this, rhs
);
723 this->base
.e
.vtable
= &MSVCP_system_error_vtable
;
729 DEFINE_THISCALL_WRAPPER(MSVCP__System_error_copy_ctor
, 8)
730 _System_error
* __thiscall
MSVCP__System_error_copy_ctor(
731 _System_error
*this, _System_error
*rhs
)
733 MSVCP_failure_copy_ctor(this, rhs
);
734 this->base
.e
.vtable
= &MSVCP__System_error_vtable
;
740 DEFINE_RTTI_DATA2(_System_error
, 0, &runtime_error_rtti_base_descriptor
,
741 &exception_rtti_base_descriptor
, ".?AV_System_error@std@@")
742 DEFINE_RTTI_DATA3(system_error
, 0, &_System_error_rtti_base_descriptor
,
743 &runtime_error_rtti_base_descriptor
, &exception_rtti_base_descriptor
,
744 ".?AVsystem_error@std@@")
745 DEFINE_RTTI_DATA4(failure
, 0, &system_error_rtti_base_descriptor
,
746 &_System_error_rtti_base_descriptor
, &runtime_error_rtti_base_descriptor
,
747 &exception_rtti_base_descriptor
, ".?AVfailure@ios_base@std@@")
748 DEFINE_CXX_TYPE_INFO(_System_error
)
749 DEFINE_CXX_TYPE_INFO(system_error
);
750 DEFINE_CXX_DATA4(failure
, &system_error_cxx_type_info
,
751 &_System_error_cxx_type_info
, &runtime_error_cxx_type_info
,
752 &exception_cxx_type_info
, MSVCP_runtime_error_dtor
)
753 #elif _MSVCP_VER > 90
754 DEFINE_RTTI_DATA2(system_error
, 0, &runtime_error_rtti_base_descriptor
,
755 &exception_rtti_base_descriptor
, ".?AVsystem_error@std@@")
756 DEFINE_RTTI_DATA3(failure
, 0, &system_error_rtti_base_descriptor
,
757 &runtime_error_rtti_base_descriptor
, &exception_rtti_base_descriptor
,
758 ".?AVfailure@ios_base@std@@")
759 DEFINE_CXX_TYPE_INFO(system_error
);
760 DEFINE_CXX_DATA3(failure
, &system_error_cxx_type_info
, &runtime_error_cxx_type_info
,
761 &exception_cxx_type_info
, MSVCP_runtime_error_dtor
)
763 DEFINE_RTTI_DATA2(failure
, 0, &runtime_error_rtti_base_descriptor
,
764 &exception_rtti_base_descriptor
, ".?AVfailure@ios_base@std@@")
765 DEFINE_CXX_DATA2(failure
, &runtime_error_cxx_type_info
,
766 &exception_cxx_type_info
, MSVCP_runtime_error_dtor
)
769 /* bad_cast class data */
770 typedef exception bad_cast
;
772 /* ??0bad_cast@std@@QAE@PBD@Z */
773 /* ??0bad_cast@std@@QEAA@PEBD@Z */
774 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_ctor
, 8)
775 bad_cast
* __thiscall
MSVCP_bad_cast_ctor(bad_cast
*this, const char *name
)
777 TRACE("%p %s\n", this, name
);
778 MSVCP_exception_ctor(this, EXCEPTION_NAME(name
));
779 this->vtable
= &MSVCP_bad_cast_vtable
;
783 /* ??_Fbad_cast@@QAEXXZ */
784 /* ??_Fbad_cast@std@@QEAAXXZ */
785 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_default_ctor
,4)
786 bad_cast
* __thiscall
MSVCP_bad_cast_default_ctor(bad_cast
*this)
788 return MSVCP_bad_cast_ctor(this, "bad cast");
791 /* ??0bad_cast@std@@QAE@ABV01@@Z */
792 /* ??0bad_cast@std@@QEAA@AEBV01@@Z */
793 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_copy_ctor
, 8)
794 bad_cast
* __thiscall
MSVCP_bad_cast_copy_ctor(bad_cast
*this, const bad_cast
*rhs
)
796 TRACE("%p %p\n", this, rhs
);
797 MSVCP_exception_copy_ctor(this, rhs
);
798 this->vtable
= &MSVCP_bad_cast_vtable
;
802 /* ??1bad_cast@@UAE@XZ */
803 /* ??1bad_cast@std@@UEAA@XZ */
804 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_dtor
, 4)
805 void __thiscall
MSVCP_bad_cast_dtor(bad_cast
*this)
808 MSVCP_exception_dtor(this);
811 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_vector_dtor
, 8)
812 void * __thiscall
MSVCP_bad_cast_vector_dtor(bad_cast
*this, unsigned int flags
)
814 TRACE("%p %x\n", this, flags
);
816 /* we have an array, with the number of elements stored before the first object */
817 INT_PTR i
, *ptr
= (INT_PTR
*)this-1;
819 for(i
=*ptr
-1; i
>=0; i
--)
820 MSVCP_bad_cast_dtor(this+i
);
821 MSVCRT_operator_delete(ptr
);
823 MSVCP_bad_cast_dtor(this);
825 MSVCRT_operator_delete(this);
831 /* ??4bad_cast@std@@QAEAAV01@ABV01@@Z */
832 /* ??4bad_cast@std@@QEAAAEAV01@AEBV01@@Z */
833 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_opequals
, 8)
834 bad_cast
* __thiscall
MSVCP_bad_cast_opequals(bad_cast
*this, const bad_cast
*rhs
)
836 TRACE("(%p %p)\n", this, rhs
);
839 MSVCP_exception_dtor(this);
840 MSVCP_exception_copy_ctor(this, rhs
);
845 DEFINE_RTTI_DATA1(bad_cast
, 0, &exception_rtti_base_descriptor
, ".?AVbad_cast@std@@")
846 DEFINE_CXX_DATA1(bad_cast
, &exception_cxx_type_info
, MSVCP_bad_cast_dtor
)
848 /* range_error class data */
849 typedef runtime_error range_error
;
851 static range_error
* MSVCP_range_error_ctor( range_error
*this, exception_name name
)
853 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
854 MSVCP_runtime_error_ctor(this, name
);
855 this->e
.vtable
= &MSVCP_range_error_vtable
;
859 /* ??0range_error@std@@QAE@ABV01@@Z */
860 /* ??0range_error@std@@QEAA@AEBV01@@Z */
861 DEFINE_THISCALL_WRAPPER(MSVCP_range_error_copy_ctor
, 8)
862 range_error
* __thiscall
MSVCP_range_error_copy_ctor(
863 range_error
*this, const range_error
*rhs
)
865 TRACE("%p %p\n", this, rhs
);
866 MSVCP_runtime_error_copy_ctor(this, rhs
);
867 this->e
.vtable
= &MSVCP_range_error_vtable
;
871 /* ??0range_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
872 /* ??0range_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
874 DEFINE_THISCALL_WRAPPER(MSVCP_range_error_ctor_bstr
, 8)
875 range_error
* __thiscall
MSVCP_range_error_ctor_bstr(range_error
*this, const basic_string_char
*str
)
877 const char *name
= MSVCP_basic_string_char_c_str(str
);
878 TRACE("(%p %p %s)\n", this, str
, name
);
879 return MSVCP_range_error_ctor(this, EXCEPTION_NAME(name
));
883 /* ??4range_error@std@@QAEAAV01@ABV01@@Z */
884 /* ??4range_error@std@@QEAAAEAV01@AEBV01@@Z */
885 DEFINE_THISCALL_WRAPPER(MSVCP_range_error_assign
, 8)
886 range_error
* __thiscall
MSVCP_range_error_assign(range_error
*this, const range_error
*assign
)
888 MSVCP_runtime_error_dtor(this);
889 return MSVCP_range_error_copy_ctor(this, assign
);
892 DEFINE_RTTI_DATA2(range_error
, 0, &runtime_error_rtti_base_descriptor
, &exception_rtti_base_descriptor
, ".?AVrange_error@std@@")
893 DEFINE_CXX_DATA2(range_error
, &runtime_error_cxx_type_info
, &exception_cxx_type_info
, MSVCP_runtime_error_dtor
)
895 /* ?_Nomemory@std@@YAXXZ */
896 void __cdecl
_Nomemory(void)
899 throw_exception(EXCEPTION_BAD_ALLOC
, NULL
);
902 /* ?_Xmem@tr1@std@@YAXXZ */
903 void __cdecl
_Xmem(void)
906 throw_exception(EXCEPTION_BAD_ALLOC
, NULL
);
909 /* ?_Xinvalid_argument@std@@YAXPBD@Z */
910 /* ?_Xinvalid_argument@std@@YAXPEBD@Z */
911 void __cdecl
_Xinvalid_argument(const char *str
)
913 TRACE("(%s)\n", debugstr_a(str
));
914 throw_exception(EXCEPTION_INVALID_ARGUMENT
, str
);
917 /* ?_Xlength_error@std@@YAXPBD@Z */
918 /* ?_Xlength_error@std@@YAXPEBD@Z */
919 void __cdecl
_Xlength_error(const char *str
)
921 TRACE("(%s)\n", debugstr_a(str
));
922 throw_exception(EXCEPTION_LENGTH_ERROR
, str
);
925 /* ?_Xout_of_range@std@@YAXPBD@Z */
926 /* ?_Xout_of_range@std@@YAXPEBD@Z */
927 void __cdecl
_Xout_of_range(const char *str
)
929 TRACE("(%s)\n", debugstr_a(str
));
930 throw_exception(EXCEPTION_OUT_OF_RANGE
, str
);
933 /* ?_Xruntime_error@std@@YAXPBD@Z */
934 /* ?_Xruntime_error@std@@YAXPEBD@Z */
935 void __cdecl
_Xruntime_error(const char *str
)
937 TRACE("(%s)\n", debugstr_a(str
));
938 throw_exception(EXCEPTION_RUNTIME_ERROR
, str
);
941 /* ?uncaught_exception@std@@YA_NXZ */
942 MSVCP_bool __cdecl
MSVCP__uncaught_exception(void)
944 return __uncaught_exception();
947 #if _MSVCP_VER >= 70 || defined(_MSVCIRT)
948 #define EXCEPTION_VTABLE(name,funcs) __ASM_VTABLE(name,funcs)
950 #define EXCEPTION_VTABLE(name,funcs) __ASM_VTABLE(name,funcs VTABLE_ADD_FUNC(MSVCP_exception__Doraise))
954 void __asm_dummy_vtables(void) {
956 __ASM_VTABLE(type_info
,
957 VTABLE_ADD_FUNC(MSVCP_type_info_vector_dtor
));
958 EXCEPTION_VTABLE(exception
,
959 VTABLE_ADD_FUNC(MSVCP_exception_vector_dtor
)
960 VTABLE_ADD_FUNC(MSVCP_exception_what
));
961 EXCEPTION_VTABLE(bad_alloc
,
962 VTABLE_ADD_FUNC(MSVCP_bad_alloc_vector_dtor
)
963 VTABLE_ADD_FUNC(MSVCP_exception_what
));
964 EXCEPTION_VTABLE(logic_error
,
965 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor
)
966 VTABLE_ADD_FUNC(MSVCP_logic_error_what
));
967 EXCEPTION_VTABLE(length_error
,
968 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor
)
969 VTABLE_ADD_FUNC(MSVCP_logic_error_what
));
970 EXCEPTION_VTABLE(out_of_range
,
971 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor
)
972 VTABLE_ADD_FUNC(MSVCP_logic_error_what
));
973 EXCEPTION_VTABLE(invalid_argument
,
974 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor
)
975 VTABLE_ADD_FUNC(MSVCP_logic_error_what
));
976 EXCEPTION_VTABLE(runtime_error
,
977 VTABLE_ADD_FUNC(MSVCP_runtime_error_vector_dtor
)
978 VTABLE_ADD_FUNC(MSVCP_runtime_error_what
));
980 EXCEPTION_VTABLE(_System_error
,
981 VTABLE_ADD_FUNC(MSVCP_failure_vector_dtor
)
982 VTABLE_ADD_FUNC(MSVCP_failure_what
));
985 EXCEPTION_VTABLE(system_error
,
986 VTABLE_ADD_FUNC(MSVCP_failure_vector_dtor
)
987 VTABLE_ADD_FUNC(MSVCP_failure_what
));
989 EXCEPTION_VTABLE(failure
,
990 VTABLE_ADD_FUNC(MSVCP_failure_vector_dtor
)
991 VTABLE_ADD_FUNC(MSVCP_failure_what
));
992 EXCEPTION_VTABLE(bad_cast
,
993 VTABLE_ADD_FUNC(MSVCP_bad_cast_vector_dtor
)
994 VTABLE_ADD_FUNC(MSVCP_exception_what
));
995 EXCEPTION_VTABLE(range_error
,
996 VTABLE_ADD_FUNC(MSVCP_runtime_error_vector_dtor
)
997 VTABLE_ADD_FUNC(MSVCP_runtime_error_what
));
1002 /* Internal: throws selected exception */
1003 void throw_exception(exception_type et
, const char *str
)
1005 exception_name name
= EXCEPTION_NAME(str
);
1008 case EXCEPTION_RERAISE
:
1009 _CxxThrowException(NULL
, NULL
);
1012 MSVCP_exception_ctor(&e
, name
);
1013 _CxxThrowException(&e
, &exception_cxx_type
);
1015 case EXCEPTION_BAD_ALLOC
: {
1017 MSVCP_bad_alloc_ctor(&e
, name
);
1018 _CxxThrowException(&e
, &bad_alloc_cxx_type
);
1020 case EXCEPTION_BAD_CAST
: {
1022 MSVCP_bad_cast_ctor(&e
, str
);
1023 _CxxThrowException(&e
, &bad_cast_cxx_type
);
1025 case EXCEPTION_LOGIC_ERROR
: {
1027 MSVCP_logic_error_ctor(&e
, name
);
1028 _CxxThrowException((exception
*)&e
, &logic_error_cxx_type
);
1030 case EXCEPTION_LENGTH_ERROR
: {
1032 MSVCP_length_error_ctor(&e
, name
);
1033 _CxxThrowException((exception
*)&e
, &length_error_cxx_type
);
1035 case EXCEPTION_OUT_OF_RANGE
: {
1037 MSVCP_out_of_range_ctor(&e
, name
);
1038 _CxxThrowException((exception
*)&e
, &out_of_range_cxx_type
);
1040 case EXCEPTION_INVALID_ARGUMENT
: {
1042 MSVCP_invalid_argument_ctor(&e
, name
);
1043 _CxxThrowException((exception
*)&e
, &invalid_argument_cxx_type
);
1045 case EXCEPTION_RUNTIME_ERROR
: {
1047 MSVCP_runtime_error_ctor(&e
, name
);
1048 _CxxThrowException((exception
*)&e
, &runtime_error_cxx_type
);
1050 case EXCEPTION_FAILURE
: {
1052 MSVCP_failure_ctor(&e
, name
);
1053 _CxxThrowException((exception
*)&e
, &failure_cxx_type
);
1055 case EXCEPTION_RANGE_ERROR
: {
1057 MSVCP_range_error_ctor(&e
, name
);
1058 _CxxThrowException((exception
*)&e
, &range_error_cxx_type
);
1063 void init_exception(void *base
)
1066 init_type_info_rtti(base
);
1067 init_exception_rtti(base
);
1068 init_bad_alloc_rtti(base
);
1069 init_logic_error_rtti(base
);
1070 init_length_error_rtti(base
);
1071 init_out_of_range_rtti(base
);
1072 init_invalid_argument_rtti(base
);
1073 init_runtime_error_rtti(base
);
1074 #if _MSVCP_VER > 110
1075 init__System_error_rtti(base
);
1078 init_system_error_rtti(base
);
1080 init_failure_rtti(base
);
1081 init_bad_cast_rtti(base
);
1082 init_range_error_rtti(base
);
1084 init_exception_cxx(base
);
1085 init_bad_alloc_cxx(base
);
1086 init_logic_error_cxx(base
);
1087 init_length_error_cxx(base
);
1088 init_out_of_range_cxx(base
);
1089 init_invalid_argument_cxx(base
);
1090 init_runtime_error_cxx(base
);
1091 #if _MSVCP_VER > 110
1092 init__System_error_cxx_type_info(base
);
1095 init_system_error_cxx_type_info(base
);
1097 init_failure_cxx(base
);
1098 init_bad_cast_cxx(base
);
1099 init_range_error_cxx(base
);