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
25 #include "wine/debug.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(msvcp
);
29 CREATE_TYPE_INFO_VTABLE
31 #define CLASS_IS_SIMPLE_TYPE 1
32 #define CLASS_HAS_VIRTUAL_BASE_CLASS 4
34 void WINAPI
_CxxThrowException(exception
*,const cxx_exception_type
*);
35 int* __cdecl
__processing_throw(void);
37 #if _MSVCP_VER >= 70 || defined(_MSVCIRT)
38 typedef const char **exception_name
;
39 #define EXCEPTION_STR(name) (*name)
40 #define EXCEPTION_NAME(str) ((exception_name)&str)
42 typedef const char *exception_name
;
43 #define EXCEPTION_STR(name) (name)
44 #define EXCEPTION_NAME(str) (str)
47 void (CDECL
*_Raise_handler
)(const exception
*) = NULL
;
50 extern const vtable_ptr exception_vtable
;
51 /* ??_7bad_alloc@std@@6B@ */
52 extern const vtable_ptr bad_alloc_vtable
;
53 /* ??_7logic_error@std@@6B@ */
54 extern const vtable_ptr logic_error_vtable
;
55 /* ??_7length_error@std@@6B@ */
56 extern const vtable_ptr length_error_vtable
;
57 /* ??_7out_of_range@std@@6B@ */
58 extern const vtable_ptr out_of_range_vtable
;
59 extern const vtable_ptr invalid_argument_vtable
;
60 /* ??_7runtime_error@std@@6B@ */
61 extern const vtable_ptr runtime_error_vtable
;
62 extern const vtable_ptr _System_error_vtable
;
63 extern const vtable_ptr system_error_vtable
;
64 extern const vtable_ptr failure_vtable
;
65 /* ??_7bad_cast@std@@6B@ */
66 extern const vtable_ptr bad_cast_vtable
;
67 /* ??_7range_error@std@@6B@ */
68 extern const vtable_ptr range_error_vtable
;
70 /* ??0exception@@QAE@ABQBD@Z */
71 /* ??0exception@@QEAA@AEBQEBD@Z */
72 DEFINE_THISCALL_WRAPPER(MSVCP_exception_ctor
,8)
73 exception
* __thiscall
MSVCP_exception_ctor(exception
*this, exception_name name
)
75 TRACE("(%p %s)\n", this, EXCEPTION_STR(name
));
77 this->vtable
= &exception_vtable
;
78 if(EXCEPTION_STR(name
)) {
79 unsigned int name_len
= strlen(EXCEPTION_STR(name
)) + 1;
80 this->name
= malloc(name_len
);
81 memcpy(this->name
, EXCEPTION_STR(name
), name_len
);
85 this->do_free
= FALSE
;
90 DEFINE_THISCALL_WRAPPER(exception_copy_ctor
,8)
91 exception
* __thiscall
exception_copy_ctor(exception
*this, const exception
*rhs
)
93 TRACE("(%p,%p)\n", this, rhs
);
96 this->vtable
= &exception_vtable
;
97 this->name
= rhs
->name
;
98 this->do_free
= FALSE
;
100 MSVCP_exception_ctor(this, EXCEPTION_NAME(rhs
->name
));
101 TRACE("name = %s\n", this->name
);
105 /* ??0exception@@QAE@XZ */
106 /* ??0exception@@QEAA@XZ */
107 DEFINE_THISCALL_WRAPPER(MSVCP_exception_default_ctor
,4)
108 exception
* __thiscall
MSVCP_exception_default_ctor(exception
*this)
110 TRACE("(%p)\n", this);
111 this->vtable
= &exception_vtable
;
113 this->do_free
= FALSE
;
117 DEFINE_THISCALL_WRAPPER(MSVCP_exception_dtor
,4)
118 void __thiscall
MSVCP_exception_dtor(exception
*this)
120 TRACE("(%p)\n", this);
121 this->vtable
= &exception_vtable
;
126 DEFINE_THISCALL_WRAPPER(MSVCP_exception_vector_dtor
, 8)
127 void * __thiscall
MSVCP_exception_vector_dtor(exception
*this, unsigned int flags
)
129 TRACE("%p %x\n", this, flags
);
131 /* we have an array, with the number of elements stored before the first object */
132 INT_PTR i
, *ptr
= (INT_PTR
*)this-1;
134 for(i
=*ptr
-1; i
>=0; i
--)
135 MSVCP_exception_dtor(this+i
);
136 MSVCRT_operator_delete(ptr
);
138 MSVCP_exception_dtor(this);
140 MSVCRT_operator_delete(this);
146 /* ??_Gexception@@UAEPAXI@Z */
147 DEFINE_THISCALL_WRAPPER(MSVCP_exception_scalar_dtor
, 8)
148 void * __thiscall
MSVCP_exception_scalar_dtor(exception
*this, unsigned int flags
)
150 TRACE("(%p %x)\n", this, flags
);
151 MSVCP_exception_dtor(this);
152 if (flags
& 1) MSVCRT_operator_delete(this);
156 /* ??4exception@@QAEAAV0@ABV0@@Z */
157 /* ??4exception@@QEAAAEAV0@AEBV0@@Z */
158 DEFINE_THISCALL_WRAPPER(MSVCP_exception_assign
, 8)
159 exception
* __thiscall
MSVCP_exception_assign(exception
*this, const exception
*assign
)
161 MSVCP_exception_dtor(this);
162 return exception_copy_ctor(this, assign
);
165 /* ?_Doraise@bad_alloc@std@@MBEXXZ */
166 /* ?_Doraise@bad_alloc@std@@MEBAXXZ */
167 /* ?_Doraise@logic_error@std@@MBEXXZ */
168 /* ?_Doraise@logic_error@std@@MEBAXXZ */
169 /* ?_Doraise@length_error@std@@MBEXXZ */
170 /* ?_Doraise@length_error@std@@MEBAXXZ */
171 /* ?_Doraise@out_of_range@std@@MBEXXZ */
172 /* ?_Doraise@out_of_range@std@@MEBAXXZ */
173 /* ?_Doraise@runtime_error@std@@MBEXXZ */
174 /* ?_Doraise@runtime_error@std@@MEBAXXZ */
175 /* ?_Doraise@bad_cast@std@@MBEXXZ */
176 /* ?_Doraise@bad_cast@std@@MEBAXXZ */
177 /* ?_Doraise@range_error@std@@MBEXXZ */
178 /* ?_Doraise@range_error@std@@MEBAXXZ */
179 DEFINE_THISCALL_WRAPPER(MSVCP_exception__Doraise
, 4)
180 void __thiscall
MSVCP_exception__Doraise(exception
*this)
182 FIXME("(%p) stub\n", this);
185 DEFINE_THISCALL_WRAPPER(MSVCP_exception_what
,4)
186 const char* __thiscall
MSVCP_exception_what(exception
* this)
188 TRACE("(%p) returning %s\n", this, this->name
);
189 return this->name
? this->name
: "Unknown exception";
193 DEFINE_RTTI_DATA0(exception
, 0, ".?AVexception@std@@")
195 DEFINE_RTTI_DATA0(exception
, 0, ".?AVexception@@")
197 DEFINE_CXX_DATA0(exception
, MSVCP_exception_dtor
)
199 /* bad_alloc class data */
200 typedef exception bad_alloc
;
202 /* ??0bad_alloc@std@@QAE@PBD@Z */
203 /* ??0bad_alloc@std@@QEAA@PEBD@Z */
204 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_ctor
, 8)
205 bad_alloc
* __thiscall
MSVCP_bad_alloc_ctor(bad_alloc
*this, exception_name name
)
207 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
208 MSVCP_exception_ctor(this, name
);
209 this->vtable
= &bad_alloc_vtable
;
213 /* ??0bad_alloc@std@@QAE@XZ */
214 /* ??0bad_alloc@std@@QEAA@XZ */
215 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_default_ctor
, 4)
216 bad_alloc
* __thiscall
MSVCP_bad_alloc_default_ctor(bad_alloc
*this)
218 static const char name
[] = "bad allocation";
219 return MSVCP_bad_alloc_ctor(this, EXCEPTION_NAME(name
));
222 /* ??0bad_alloc@std@@QAE@ABV01@@Z */
223 /* ??0bad_alloc@std@@QEAA@AEBV01@@Z */
224 DEFINE_THISCALL_WRAPPER(bad_alloc_copy_ctor
, 8)
225 bad_alloc
* __thiscall
bad_alloc_copy_ctor(bad_alloc
*this, const bad_alloc
*rhs
)
227 TRACE("%p %p\n", this, rhs
);
228 exception_copy_ctor(this, rhs
);
229 this->vtable
= &bad_alloc_vtable
;
233 /* ??1bad_alloc@std@@UAE@XZ */
234 /* ??1bad_alloc@std@@UEAA@XZ */
235 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_dtor
, 4)
236 void __thiscall
MSVCP_bad_alloc_dtor(bad_alloc
*this)
239 MSVCP_exception_dtor(this);
242 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_vector_dtor
, 8)
243 void * __thiscall
MSVCP_bad_alloc_vector_dtor(bad_alloc
*this, unsigned int flags
)
245 TRACE("%p %x\n", this, flags
);
247 /* we have an array, with the number of elements stored before the first object */
248 INT_PTR i
, *ptr
= (INT_PTR
*)this-1;
250 for(i
=*ptr
-1; i
>=0; i
--)
251 MSVCP_bad_alloc_dtor(this+i
);
252 MSVCRT_operator_delete(ptr
);
254 MSVCP_bad_alloc_dtor(this);
256 MSVCRT_operator_delete(this);
262 /* ??4bad_alloc@std@@QAEAAV01@ABV01@@Z */
263 /* ??4bad_alloc@std@@QEAAAEAV01@AEBV01@@Z */
264 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_assign
, 8)
265 bad_alloc
* __thiscall
MSVCP_bad_alloc_assign(bad_alloc
*this, const bad_alloc
*assign
)
267 MSVCP_bad_alloc_dtor(this);
268 return bad_alloc_copy_ctor(this, assign
);
271 DEFINE_RTTI_DATA1(bad_alloc
, 0, &exception_rtti_base_descriptor
, ".?AVbad_alloc@std@@")
272 DEFINE_CXX_DATA1(bad_alloc
, &exception_cxx_type_info
, MSVCP_bad_alloc_dtor
)
274 /* logic_error class data */
277 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
278 basic_string_char str
;
282 /* ??0logic_error@@QAE@ABQBD@Z */
283 /* ??0logic_error@@QEAA@AEBQEBD@Z */
284 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_ctor
, 8)
285 logic_error
* __thiscall
MSVCP_logic_error_ctor( logic_error
*this, exception_name name
)
287 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
288 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
290 MSVCP_exception_ctor(&this->e
, "");
292 MSVCP_exception_default_ctor(&this->e
);
294 MSVCP_basic_string_char_ctor_cstr(&this->str
, EXCEPTION_STR(name
));
296 MSVCP_exception_ctor(&this->e
, name
);
298 this->e
.vtable
= &logic_error_vtable
;
302 /* ??0logic_error@std@@QAE@ABV01@@Z */
303 /* ??0logic_error@std@@QEAA@AEBV01@@Z */
304 DEFINE_THISCALL_WRAPPER(logic_error_copy_ctor
, 8)
305 logic_error
* __thiscall
logic_error_copy_ctor(
306 logic_error
*this, const logic_error
*rhs
)
308 TRACE("%p %p\n", this, rhs
);
309 exception_copy_ctor(&this->e
, &rhs
->e
);
310 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
311 MSVCP_basic_string_char_copy_ctor(&this->str
, &rhs
->str
);
313 this->e
.vtable
= &logic_error_vtable
;
317 /* ??0logic_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
318 /* ??0logic_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
320 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_ctor_bstr
, 8)
321 logic_error
* __thiscall
MSVCP_logic_error_ctor_bstr(logic_error
*this, const basic_string_char
*str
)
323 const char *name
= MSVCP_basic_string_char_c_str(str
);
324 TRACE("(%p %p %s)\n", this, str
, name
);
325 return MSVCP_logic_error_ctor(this, EXCEPTION_NAME(name
));
329 /* ??1logic_error@std@@UAE@XZ */
330 /* ??1logic_error@std@@UEAA@XZ */
331 /* ??1length_error@std@@UAE@XZ */
332 /* ??1length_error@std@@UEAA@XZ */
333 /* ??1out_of_range@std@@UAE@XZ */
334 /* ??1out_of_range@std@@UEAA@XZ */
335 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_dtor
, 4)
336 void __thiscall
MSVCP_logic_error_dtor(logic_error
*this)
339 MSVCP_exception_dtor(&this->e
);
340 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
341 MSVCP_basic_string_char_dtor(&this->str
);
345 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_vector_dtor
, 8)
346 void* __thiscall
MSVCP_logic_error_vector_dtor(
347 logic_error
*this, unsigned int flags
)
349 TRACE("%p %x\n", this, flags
);
351 /* we have an array, with the number of elements stored before the first object */
352 INT_PTR i
, *ptr
= (INT_PTR
*)this-1;
354 for(i
=*ptr
-1; i
>=0; i
--)
355 MSVCP_logic_error_dtor(this+i
);
356 MSVCRT_operator_delete(ptr
);
358 MSVCP_logic_error_dtor(this);
360 MSVCRT_operator_delete(this);
366 /* ??_Glogic_error@@UAEPAXI@Z */
367 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_scalar_dtor
, 8)
368 void * __thiscall
MSVCP_logic_error_scalar_dtor(logic_error
*this, unsigned int flags
)
370 TRACE("(%p %x)\n", this, flags
);
371 MSVCP_logic_error_dtor(this);
372 if (flags
& 1) MSVCRT_operator_delete(this);
376 /* ??4logic_error@std@@QAEAAV01@ABV01@@Z */
377 /* ??4logic_error@std@@QEAAAEAV01@AEBV01@@Z */
378 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_assign
, 8)
379 logic_error
* __thiscall
MSVCP_logic_error_assign(logic_error
*this, const logic_error
*assign
)
381 MSVCP_logic_error_dtor(this);
382 return logic_error_copy_ctor(this, assign
);
385 /* ?what@logic_error@std@@UBEPBDXZ */
386 /* ?what@logic_error@std@@UEBAPEBDXZ */
387 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_what
, 4)
388 const char* __thiscall
MSVCP_logic_error_what(logic_error
*this)
391 #if _MSVCP_VER > 90 || defined _MSVCIRT
392 return MSVCP_exception_what( &this->e
);
394 return MSVCP_basic_string_char_c_str(&this->str
);
399 DEFINE_RTTI_DATA1(logic_error
, 0, &exception_rtti_base_descriptor
, ".?AVlogic_error@std@@")
401 DEFINE_RTTI_DATA1(logic_error
, 0, &exception_rtti_base_descriptor
, ".?AVlogic_error@@")
403 DEFINE_CXX_DATA1(logic_error
, &exception_cxx_type_info
, MSVCP_logic_error_dtor
)
405 /* length_error class data */
406 typedef logic_error length_error
;
408 static length_error
* MSVCP_length_error_ctor( length_error
*this, exception_name name
)
410 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
411 MSVCP_logic_error_ctor(this, name
);
412 this->e
.vtable
= &length_error_vtable
;
416 /* ??0length_error@std@@QAE@ABV01@@Z */
417 /* ??0length_error@std@@QEAA@AEBV01@@Z */
418 DEFINE_THISCALL_WRAPPER(length_error_copy_ctor
, 8)
419 length_error
* __thiscall
length_error_copy_ctor(
420 length_error
*this, const length_error
*rhs
)
422 TRACE("%p %p\n", this, rhs
);
423 logic_error_copy_ctor(this, rhs
);
424 this->e
.vtable
= &length_error_vtable
;
428 /* ??0length_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
429 /* ??0length_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
431 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_ctor_bstr
, 8)
432 length_error
* __thiscall
MSVCP_length_error_ctor_bstr(length_error
*this, const basic_string_char
*str
)
434 const char *name
= MSVCP_basic_string_char_c_str(str
);
435 TRACE("(%p %p %s)\n", this, str
, name
);
436 return MSVCP_length_error_ctor(this, EXCEPTION_NAME(name
));
440 /* ??4length_error@std@@QAEAAV01@ABV01@@Z */
441 /* ??4length_error@std@@QEAAAEAV01@AEBV01@@Z */
442 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_assign
, 8)
443 length_error
* __thiscall
MSVCP_length_error_assign(length_error
*this, const length_error
*assign
)
445 MSVCP_logic_error_dtor(this);
446 return length_error_copy_ctor(this, assign
);
449 DEFINE_RTTI_DATA2(length_error
, 0, &logic_error_rtti_base_descriptor
, &exception_rtti_base_descriptor
, ".?AVlength_error@std@@")
450 DEFINE_CXX_DATA2(length_error
, &logic_error_cxx_type_info
, &exception_cxx_type_info
, MSVCP_logic_error_dtor
)
452 /* out_of_range class data */
453 typedef logic_error out_of_range
;
455 static out_of_range
* MSVCP_out_of_range_ctor( out_of_range
*this, exception_name name
)
457 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
458 MSVCP_logic_error_ctor(this, name
);
459 this->e
.vtable
= &out_of_range_vtable
;
463 /* ??0out_of_range@std@@QAE@ABV01@@Z */
464 /* ??0out_of_range@std@@QEAA@AEBV01@@Z */
465 DEFINE_THISCALL_WRAPPER(out_of_range_copy_ctor
, 8)
466 out_of_range
* __thiscall
out_of_range_copy_ctor(
467 out_of_range
*this, const out_of_range
*rhs
)
469 TRACE("%p %p\n", this, rhs
);
470 logic_error_copy_ctor(this, rhs
);
471 this->e
.vtable
= &out_of_range_vtable
;
475 /* ??0out_of_range@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
476 /* ??0out_of_range@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
478 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_ctor_bstr
, 8)
479 out_of_range
* __thiscall
MSVCP_out_of_range_ctor_bstr(out_of_range
*this, const basic_string_char
*str
)
481 const char *name
= MSVCP_basic_string_char_c_str(str
);
482 TRACE("(%p %p %s)\n", this, str
, name
);
483 return MSVCP_out_of_range_ctor(this, EXCEPTION_NAME(name
));
487 /* ??4out_of_range@std@@QAEAAV01@ABV01@@Z */
488 /* ??4out_of_range@std@@QEAAAEAV01@AEBV01@@Z */
489 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_assign
, 8)
490 out_of_range
* __thiscall
MSVCP_out_of_range_assign(out_of_range
*this, const out_of_range
*assign
)
492 MSVCP_logic_error_dtor(this);
493 return out_of_range_copy_ctor(this, assign
);
496 DEFINE_RTTI_DATA2(out_of_range
, 0, &logic_error_rtti_base_descriptor
, &exception_rtti_base_descriptor
, ".?AVout_of_range@std@@")
497 DEFINE_CXX_DATA2(out_of_range
, &logic_error_cxx_type_info
, &exception_cxx_type_info
, MSVCP_logic_error_dtor
)
499 /* invalid_argument class data */
500 typedef logic_error invalid_argument
;
502 static invalid_argument
* MSVCP_invalid_argument_ctor( invalid_argument
*this, exception_name name
)
504 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
505 MSVCP_logic_error_ctor(this, name
);
506 this->e
.vtable
= &invalid_argument_vtable
;
510 DEFINE_THISCALL_WRAPPER(invalid_argument_copy_ctor
, 8)
511 invalid_argument
* __thiscall
invalid_argument_copy_ctor(
512 invalid_argument
*this, invalid_argument
*rhs
)
514 TRACE("%p %p\n", this, rhs
);
515 logic_error_copy_ctor(this, rhs
);
516 this->e
.vtable
= &invalid_argument_vtable
;
520 DEFINE_RTTI_DATA2(invalid_argument
, 0, &logic_error_rtti_base_descriptor
, &exception_rtti_base_descriptor
, ".?AVinvalid_argument@std@@")
521 DEFINE_CXX_DATA2(invalid_argument
, &logic_error_cxx_type_info
, &exception_cxx_type_info
, MSVCP_logic_error_dtor
)
523 /* runtime_error class data */
526 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
527 basic_string_char str
;
531 static runtime_error
* MSVCP_runtime_error_ctor( runtime_error
*this, exception_name name
)
533 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
534 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
536 MSVCP_exception_ctor(&this->e
, "");
538 MSVCP_exception_default_ctor(&this->e
);
540 MSVCP_basic_string_char_ctor_cstr(&this->str
, EXCEPTION_STR(name
));
542 MSVCP_exception_ctor(&this->e
, name
);
544 this->e
.vtable
= &runtime_error_vtable
;
548 /* ??0runtime_error@std@@QAE@ABV01@@Z */
549 /* ??0runtime_error@std@@QEAA@AEBV01@@Z */
550 DEFINE_THISCALL_WRAPPER(runtime_error_copy_ctor
, 8)
551 runtime_error
* __thiscall
runtime_error_copy_ctor(
552 runtime_error
*this, const runtime_error
*rhs
)
554 TRACE("%p %p\n", this, rhs
);
555 exception_copy_ctor(&this->e
, &rhs
->e
);
556 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
557 MSVCP_basic_string_char_copy_ctor(&this->str
, &rhs
->str
);
559 this->e
.vtable
= &runtime_error_vtable
;
563 /* ??0runtime_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
564 /* ??0runtime_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
566 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_ctor_bstr
, 8)
567 runtime_error
* __thiscall
MSVCP_runtime_error_ctor_bstr(runtime_error
*this, const basic_string_char
*str
)
569 const char *name
= MSVCP_basic_string_char_c_str(str
);
570 TRACE("(%p %p %s)\n", this, str
, name
);
571 return MSVCP_runtime_error_ctor(this, EXCEPTION_NAME(name
));
575 /* ??1runtime_error@std@@UAE@XZ */
576 /* ??1runtime_error@std@@UEAA@XZ */
577 /* ??1range_error@std@@UAE@XZ */
578 /* ??1range_error@std@@UEAA@XZ */
579 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_dtor
, 4)
580 void __thiscall
MSVCP_runtime_error_dtor(runtime_error
*this)
583 MSVCP_exception_dtor(&this->e
);
584 #if _MSVCP_VER <= 90 && !defined _MSVCIRT
585 MSVCP_basic_string_char_dtor(&this->str
);
589 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_vector_dtor
, 8)
590 void* __thiscall
MSVCP_runtime_error_vector_dtor(
591 runtime_error
*this, unsigned int flags
)
593 TRACE("%p %x\n", this, flags
);
595 /* we have an array, with the number of elements stored before the first object */
596 INT_PTR i
, *ptr
= (INT_PTR
*)this-1;
598 for(i
=*ptr
-1; i
>=0; i
--)
599 MSVCP_runtime_error_dtor(this+i
);
600 MSVCRT_operator_delete(ptr
);
602 MSVCP_runtime_error_dtor(this);
604 MSVCRT_operator_delete(this);
610 /* ??4runtime_error@std@@QAEAAV01@ABV01@@Z */
611 /* ??4runtime_error@std@@QEAAAEAV01@AEBV01@@Z */
612 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_assign
, 8)
613 runtime_error
* __thiscall
MSVCP_runtime_error_assign(runtime_error
*this, const runtime_error
*assign
)
615 MSVCP_runtime_error_dtor(this);
616 return runtime_error_copy_ctor(this, assign
);
619 /* ?what@runtime_error@std@@UBEPBDXZ */
620 /* ?what@runtime_error@std@@UEBAPEBDXZ */
621 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_what
, 4)
622 const char* __thiscall
MSVCP_runtime_error_what(runtime_error
*this)
625 #if _MSVCP_VER > 90 || defined _MSVCIRT
626 return MSVCP_exception_what( &this->e
);
628 return MSVCP_basic_string_char_c_str(&this->str
);
632 DEFINE_RTTI_DATA1(runtime_error
, 0, &exception_rtti_base_descriptor
, ".?AVruntime_error@std@@")
633 DEFINE_CXX_DATA1(runtime_error
, &exception_cxx_type_info
, MSVCP_runtime_error_dtor
)
635 /* failure class data */
642 typedef system_error _System_error
;
643 typedef system_error failure
;
645 static failure
* MSVCP_failure_ctor( failure
*this, exception_name name
)
647 TRACE("%p %s\n", this, EXCEPTION_STR(name
));
648 MSVCP_runtime_error_ctor(&this->base
, name
);
650 /* FIXME: set err correctly */
653 this->base
.e
.vtable
= &failure_vtable
;
657 DEFINE_THISCALL_WRAPPER(failure_copy_ctor
, 8)
658 failure
* __thiscall
failure_copy_ctor(
659 failure
*this, failure
*rhs
)
661 TRACE("%p %p\n", this, rhs
);
662 runtime_error_copy_ctor(&this->base
, &rhs
->base
);
664 this->err
= rhs
->err
;
666 this->base
.e
.vtable
= &failure_vtable
;
670 DEFINE_THISCALL_WRAPPER(MSVCP_failure_dtor
, 4)
671 void __thiscall
MSVCP_failure_dtor(failure
*this)
674 MSVCP_runtime_error_dtor(&this->base
);
677 DEFINE_THISCALL_WRAPPER(MSVCP_failure_vector_dtor
, 8)
678 void* __thiscall
MSVCP_failure_vector_dtor(
679 failure
*this, unsigned int flags
)
681 TRACE("%p %x\n", this, flags
);
682 return MSVCP_runtime_error_vector_dtor(&this->base
, flags
);
685 DEFINE_THISCALL_WRAPPER(MSVCP_failure_what
, 4)
686 const char* __thiscall
MSVCP_failure_what(failure
*this)
689 return MSVCP_runtime_error_what(&this->base
);
693 DEFINE_THISCALL_WRAPPER(system_error_copy_ctor
, 8)
694 system_error
* __thiscall
system_error_copy_ctor(
695 system_error
*this, system_error
*rhs
)
697 failure_copy_ctor(this, rhs
);
698 this->base
.e
.vtable
= &system_error_vtable
;
704 DEFINE_THISCALL_WRAPPER(_System_error_copy_ctor
, 8)
705 _System_error
* __thiscall
_System_error_copy_ctor(
706 _System_error
*this, _System_error
*rhs
)
708 failure_copy_ctor(this, rhs
);
709 this->base
.e
.vtable
= &_System_error_vtable
;
715 DEFINE_RTTI_DATA2(_System_error
, 0, &runtime_error_rtti_base_descriptor
,
716 &exception_rtti_base_descriptor
, ".?AV_System_error@std@@")
717 DEFINE_RTTI_DATA3(system_error
, 0, &_System_error_rtti_base_descriptor
,
718 &runtime_error_rtti_base_descriptor
, &exception_rtti_base_descriptor
,
719 ".?AVsystem_error@std@@")
720 DEFINE_RTTI_DATA4(failure
, 0, &system_error_rtti_base_descriptor
,
721 &_System_error_rtti_base_descriptor
, &runtime_error_rtti_base_descriptor
,
722 &exception_rtti_base_descriptor
, ".?AVfailure@ios_base@std@@")
723 DEFINE_CXX_TYPE_INFO(_System_error
)
724 DEFINE_CXX_TYPE_INFO(system_error
);
725 DEFINE_CXX_DATA4(failure
, &system_error_cxx_type_info
,
726 &_System_error_cxx_type_info
, &runtime_error_cxx_type_info
,
727 &exception_cxx_type_info
, MSVCP_runtime_error_dtor
)
728 #elif _MSVCP_VER > 90
729 DEFINE_RTTI_DATA2(system_error
, 0, &runtime_error_rtti_base_descriptor
,
730 &exception_rtti_base_descriptor
, ".?AVsystem_error@std@@")
731 DEFINE_RTTI_DATA3(failure
, 0, &system_error_rtti_base_descriptor
,
732 &runtime_error_rtti_base_descriptor
, &exception_rtti_base_descriptor
,
733 ".?AVfailure@ios_base@std@@")
734 DEFINE_CXX_TYPE_INFO(system_error
);
735 DEFINE_CXX_DATA3(failure
, &system_error_cxx_type_info
, &runtime_error_cxx_type_info
,
736 &exception_cxx_type_info
, MSVCP_runtime_error_dtor
)
738 DEFINE_RTTI_DATA2(failure
, 0, &runtime_error_rtti_base_descriptor
,
739 &exception_rtti_base_descriptor
, ".?AVfailure@ios_base@std@@")
740 DEFINE_CXX_DATA2(failure
, &runtime_error_cxx_type_info
,
741 &exception_cxx_type_info
, MSVCP_runtime_error_dtor
)
744 /* bad_cast class data */
745 typedef exception bad_cast
;
747 /* ??0bad_cast@std@@QAE@PBD@Z */
748 /* ??0bad_cast@std@@QEAA@PEBD@Z */
749 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_ctor
, 8)
750 bad_cast
* __thiscall
MSVCP_bad_cast_ctor(bad_cast
*this, const char *name
)
752 TRACE("%p %s\n", this, name
);
753 MSVCP_exception_ctor(this, EXCEPTION_NAME(name
));
754 this->vtable
= &bad_cast_vtable
;
758 /* ??_Fbad_cast@@QAEXXZ */
759 /* ??_Fbad_cast@std@@QEAAXXZ */
760 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_default_ctor
,4)
761 bad_cast
* __thiscall
MSVCP_bad_cast_default_ctor(bad_cast
*this)
763 return MSVCP_bad_cast_ctor(this, "bad cast");
766 /* ??0bad_cast@std@@QAE@ABV01@@Z */
767 /* ??0bad_cast@std@@QEAA@AEBV01@@Z */
768 DEFINE_THISCALL_WRAPPER(bad_cast_copy_ctor
, 8)
769 bad_cast
* __thiscall
bad_cast_copy_ctor(bad_cast
*this, const bad_cast
*rhs
)
771 TRACE("%p %p\n", this, rhs
);
772 exception_copy_ctor(this, rhs
);
773 this->vtable
= &bad_cast_vtable
;
777 /* ??1bad_cast@@UAE@XZ */
778 /* ??1bad_cast@std@@UEAA@XZ */
779 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_dtor
, 4)
780 void __thiscall
MSVCP_bad_cast_dtor(bad_cast
*this)
783 MSVCP_exception_dtor(this);
786 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_vector_dtor
, 8)
787 void * __thiscall
MSVCP_bad_cast_vector_dtor(bad_cast
*this, unsigned int flags
)
789 TRACE("%p %x\n", this, flags
);
791 /* we have an array, with the number of elements stored before the first object */
792 INT_PTR i
, *ptr
= (INT_PTR
*)this-1;
794 for(i
=*ptr
-1; i
>=0; i
--)
795 MSVCP_bad_cast_dtor(this+i
);
796 MSVCRT_operator_delete(ptr
);
798 MSVCP_bad_cast_dtor(this);
800 MSVCRT_operator_delete(this);
806 /* ??4bad_cast@std@@QAEAAV01@ABV01@@Z */
807 /* ??4bad_cast@std@@QEAAAEAV01@AEBV01@@Z */
808 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_opequals
, 8)
809 bad_cast
* __thiscall
MSVCP_bad_cast_opequals(bad_cast
*this, const bad_cast
*rhs
)
811 TRACE("(%p %p)\n", this, rhs
);
814 MSVCP_exception_dtor(this);
815 exception_copy_ctor(this, rhs
);
820 DEFINE_RTTI_DATA1(bad_cast
, 0, &exception_rtti_base_descriptor
, ".?AVbad_cast@std@@")
821 DEFINE_CXX_DATA1(bad_cast
, &exception_cxx_type_info
, MSVCP_bad_cast_dtor
)
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
;
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
;
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 */
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
));
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
_Nomemory(void)
874 throw_exception(EXCEPTION_BAD_ALLOC
, NULL
);
877 /* ?_Xmem@tr1@std@@YAXXZ */
878 void __cdecl
_Xmem(void)
881 throw_exception(EXCEPTION_BAD_ALLOC
, NULL
);
884 /* ?_Xinvalid_argument@std@@YAXPBD@Z */
885 /* ?_Xinvalid_argument@std@@YAXPEBD@Z */
886 void __cdecl
_Xinvalid_argument(const char *str
)
888 TRACE("(%s)\n", debugstr_a(str
));
889 throw_exception(EXCEPTION_INVALID_ARGUMENT
, str
);
892 /* ?_Xlength_error@std@@YAXPBD@Z */
893 /* ?_Xlength_error@std@@YAXPEBD@Z */
894 void __cdecl
_Xlength_error(const char *str
)
896 TRACE("(%s)\n", debugstr_a(str
));
897 throw_exception(EXCEPTION_LENGTH_ERROR
, str
);
900 /* ?_Xout_of_range@std@@YAXPBD@Z */
901 /* ?_Xout_of_range@std@@YAXPEBD@Z */
902 void __cdecl
_Xout_of_range(const char *str
)
904 TRACE("(%s)\n", debugstr_a(str
));
905 throw_exception(EXCEPTION_OUT_OF_RANGE
, str
);
908 /* ?_Xruntime_error@std@@YAXPBD@Z */
909 /* ?_Xruntime_error@std@@YAXPEBD@Z */
910 void __cdecl
_Xruntime_error(const char *str
)
912 TRACE("(%s)\n", debugstr_a(str
));
913 throw_exception(EXCEPTION_RUNTIME_ERROR
, str
);
916 /* ?uncaught_exception@std@@YA_NXZ */
917 bool __cdecl
MSVCP__uncaught_exception(void)
919 return __uncaught_exception();
922 #if _MSVCP_VER >= 140
923 int __cdecl
__uncaught_exceptions(void)
925 return *__processing_throw();
930 EXCEPTION_RECORD
*rec
;
931 int *ref
; /* not binary compatible with native */
934 /*********************************************************************
935 * ?__ExceptionPtrCreate@@YAXPAX@Z
936 * ?__ExceptionPtrCreate@@YAXPEAX@Z
938 void __cdecl
__ExceptionPtrCreate(exception_ptr
*ep
)
946 #ifdef __ASM_USE_THISCALL_WRAPPER
947 extern void call_dtor(const cxx_exception_type
*type
, void *func
, void *object
);
949 __ASM_GLOBAL_FUNC( call_dtor
,
950 "movl 12(%esp),%ecx\n\t"
954 static inline void call_dtor(const cxx_exception_type
*type
, unsigned int dtor
, void *object
)
956 char *base
= RtlPcToFileHeader((void*)type
, (void**)&base
);
957 void (__cdecl
*func
)(void*) = (void*)(base
+ dtor
);
961 #define call_dtor(type, func, object) ((void (__thiscall*)(void*))(func))(object)
964 /*********************************************************************
965 * ?__ExceptionPtrDestroy@@YAXPAX@Z
966 * ?__ExceptionPtrDestroy@@YAXPEAX@Z
968 void __cdecl
__ExceptionPtrDestroy(exception_ptr
*ep
)
975 if (!InterlockedDecrement(ep
->ref
))
977 if (ep
->rec
->ExceptionCode
== CXX_EXCEPTION
)
979 const cxx_exception_type
*type
= (void*)ep
->rec
->ExceptionInformation
[2];
980 void *obj
= (void*)ep
->rec
->ExceptionInformation
[1];
982 if (type
&& type
->destructor
) call_dtor(type
, type
->destructor
, obj
);
983 HeapFree(GetProcessHeap(), 0, obj
);
986 HeapFree(GetProcessHeap(), 0, ep
->rec
);
987 HeapFree(GetProcessHeap(), 0, ep
->ref
);
992 #if _MSVCP_VER >= 70 || defined(_MSVCIRT)
993 #define EXCEPTION_VTABLE(name,funcs) __ASM_VTABLE(name,funcs)
995 #define EXCEPTION_VTABLE(name,funcs) __ASM_VTABLE(name,funcs VTABLE_ADD_FUNC(MSVCP_exception__Doraise))
998 __ASM_BLOCK_BEGIN(exception_vtables
)
999 EXCEPTION_VTABLE(exception
,
1000 VTABLE_ADD_FUNC(MSVCP_exception_vector_dtor
)
1001 VTABLE_ADD_FUNC(MSVCP_exception_what
));
1002 EXCEPTION_VTABLE(bad_alloc
,
1003 VTABLE_ADD_FUNC(MSVCP_bad_alloc_vector_dtor
)
1004 VTABLE_ADD_FUNC(MSVCP_exception_what
));
1005 EXCEPTION_VTABLE(logic_error
,
1006 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor
)
1007 VTABLE_ADD_FUNC(MSVCP_logic_error_what
));
1008 EXCEPTION_VTABLE(length_error
,
1009 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor
)
1010 VTABLE_ADD_FUNC(MSVCP_logic_error_what
));
1011 EXCEPTION_VTABLE(out_of_range
,
1012 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor
)
1013 VTABLE_ADD_FUNC(MSVCP_logic_error_what
));
1014 EXCEPTION_VTABLE(invalid_argument
,
1015 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor
)
1016 VTABLE_ADD_FUNC(MSVCP_logic_error_what
));
1017 EXCEPTION_VTABLE(runtime_error
,
1018 VTABLE_ADD_FUNC(MSVCP_runtime_error_vector_dtor
)
1019 VTABLE_ADD_FUNC(MSVCP_runtime_error_what
));
1020 #if _MSVCP_VER > 110
1021 EXCEPTION_VTABLE(_System_error
,
1022 VTABLE_ADD_FUNC(MSVCP_failure_vector_dtor
)
1023 VTABLE_ADD_FUNC(MSVCP_failure_what
));
1026 EXCEPTION_VTABLE(system_error
,
1027 VTABLE_ADD_FUNC(MSVCP_failure_vector_dtor
)
1028 VTABLE_ADD_FUNC(MSVCP_failure_what
));
1030 EXCEPTION_VTABLE(failure
,
1031 VTABLE_ADD_FUNC(MSVCP_failure_vector_dtor
)
1032 VTABLE_ADD_FUNC(MSVCP_failure_what
));
1033 EXCEPTION_VTABLE(bad_cast
,
1034 VTABLE_ADD_FUNC(MSVCP_bad_cast_vector_dtor
)
1035 VTABLE_ADD_FUNC(MSVCP_exception_what
));
1036 EXCEPTION_VTABLE(range_error
,
1037 VTABLE_ADD_FUNC(MSVCP_runtime_error_vector_dtor
)
1038 VTABLE_ADD_FUNC(MSVCP_runtime_error_what
));
1041 /* Internal: throws selected exception */
1042 void throw_exception(exception_type et
, const char *str
)
1044 exception_name name
= EXCEPTION_NAME(str
);
1047 case EXCEPTION_RERAISE
:
1048 _CxxThrowException(NULL
, NULL
);
1051 MSVCP_exception_ctor(&e
, name
);
1052 _CxxThrowException(&e
, &exception_cxx_type
);
1054 case EXCEPTION_BAD_ALLOC
: {
1056 MSVCP_bad_alloc_ctor(&e
, name
);
1057 _CxxThrowException(&e
, &bad_alloc_cxx_type
);
1059 case EXCEPTION_BAD_CAST
: {
1061 MSVCP_bad_cast_ctor(&e
, str
);
1062 _CxxThrowException(&e
, &bad_cast_cxx_type
);
1064 case EXCEPTION_LOGIC_ERROR
: {
1066 MSVCP_logic_error_ctor(&e
, name
);
1067 _CxxThrowException((exception
*)&e
, &logic_error_cxx_type
);
1069 case EXCEPTION_LENGTH_ERROR
: {
1071 MSVCP_length_error_ctor(&e
, name
);
1072 _CxxThrowException((exception
*)&e
, &length_error_cxx_type
);
1074 case EXCEPTION_OUT_OF_RANGE
: {
1076 MSVCP_out_of_range_ctor(&e
, name
);
1077 _CxxThrowException((exception
*)&e
, &out_of_range_cxx_type
);
1079 case EXCEPTION_INVALID_ARGUMENT
: {
1081 MSVCP_invalid_argument_ctor(&e
, name
);
1082 _CxxThrowException((exception
*)&e
, &invalid_argument_cxx_type
);
1084 case EXCEPTION_RUNTIME_ERROR
: {
1086 MSVCP_runtime_error_ctor(&e
, name
);
1087 _CxxThrowException((exception
*)&e
, &runtime_error_cxx_type
);
1089 case EXCEPTION_FAILURE
: {
1091 MSVCP_failure_ctor(&e
, name
);
1092 _CxxThrowException((exception
*)&e
, &failure_cxx_type
);
1094 case EXCEPTION_RANGE_ERROR
: {
1096 MSVCP_range_error_ctor(&e
, name
);
1097 _CxxThrowException((exception
*)&e
, &range_error_cxx_type
);
1102 void init_exception(void *base
)
1105 init_type_info_rtti(base
);
1106 init_exception_rtti(base
);
1107 init_bad_alloc_rtti(base
);
1108 init_logic_error_rtti(base
);
1109 init_length_error_rtti(base
);
1110 init_out_of_range_rtti(base
);
1111 init_invalid_argument_rtti(base
);
1112 init_runtime_error_rtti(base
);
1113 #if _MSVCP_VER > 110
1114 init__System_error_rtti(base
);
1117 init_system_error_rtti(base
);
1119 init_failure_rtti(base
);
1120 init_bad_cast_rtti(base
);
1121 init_range_error_rtti(base
);
1123 init_exception_cxx(base
);
1124 init_bad_alloc_cxx(base
);
1125 init_logic_error_cxx(base
);
1126 init_length_error_cxx(base
);
1127 init_out_of_range_cxx(base
);
1128 init_invalid_argument_cxx(base
);
1129 init_runtime_error_cxx(base
);
1130 #if _MSVCP_VER > 110
1131 init__System_error_cxx_type_info(base
);
1134 init_system_error_cxx_type_info(base
);
1136 init_failure_cxx(base
);
1137 init_bad_cast_cxx(base
);
1138 init_range_error_cxx(base
);