msvcp60: Export basic_ostream constructors.
[wine] / dlls / msvcp60 / exception.c
1 /*
2  * Copyright 2010 Piotr Caban for CodeWeavers
3  *
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.
8  *
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.
13  *
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
17  */
18
19 #include "config.h"
20
21 #include <stdarg.h>
22
23 #include "msvcp.h"
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(msvcp);
29
30 #define CLASS_IS_SIMPLE_TYPE          1
31 #define CLASS_HAS_VIRTUAL_BASE_CLASS  4
32
33 void WINAPI _CxxThrowException(exception*,const cxx_exception_type*);
34
35 /* vtables */
36 extern const vtable_ptr MSVCP_type_info_vtable;
37 extern const vtable_ptr MSVCP_exception_vtable;
38 /* ??_7bad_alloc@std@@6B@ */
39 extern const vtable_ptr MSVCP_bad_alloc_vtable;
40 /* ??_7logic_error@std@@6B@ */
41 extern const vtable_ptr MSVCP_logic_error_vtable;
42 /* ??_7length_error@std@@6B@ */
43 extern const vtable_ptr MSVCP_length_error_vtable;
44 /* ??_7out_of_range@std@@6B@ */
45 extern const vtable_ptr MSVCP_out_of_range_vtable;
46 extern const vtable_ptr MSVCP_invalid_argument_vtable;
47 /* ??_7runtime_error@std@@6B@ */
48 extern const vtable_ptr MSVCP_runtime_error_vtable;
49 extern const vtable_ptr MSVCP_failure_vtable;
50
51 static void MSVCP_type_info_dtor(type_info * _this)
52 {
53     free(_this->name);
54 }
55
56 DEFINE_THISCALL_WRAPPER(MSVCP_type_info_vector_dtor,8)
57 void * __thiscall MSVCP_type_info_vector_dtor(type_info * _this, unsigned int flags)
58 {
59     TRACE("(%p %x)\n", _this, flags);
60     if (flags & 2)
61     {
62         /* we have an array, with the number of elements stored before the first object */
63         INT_PTR i, *ptr = (INT_PTR *)_this - 1;
64
65         for (i = *ptr - 1; i >= 0; i--) MSVCP_type_info_dtor(_this + i);
66         MSVCRT_operator_delete(ptr);
67     }
68     else
69     {
70         MSVCP_type_info_dtor(_this);
71         if (flags & 1) MSVCRT_operator_delete(_this);
72     }
73     return _this;
74 }
75
76 DEFINE_RTTI_DATA0( type_info, 0, ".?AVtype_info@@" );
77
78 static exception* MSVCP_exception_ctor(exception *this, const char *name)
79 {
80     TRACE("(%p %s)\n", this, name);
81
82     this->vtable = &MSVCP_exception_vtable;
83     if(name) {
84         unsigned int name_len = strlen(name) + 1;
85         this->name = malloc(name_len);
86         memcpy(this->name, name, name_len);
87         this->do_free = TRUE;
88     } else {
89         this->name = NULL;
90         this->do_free = FALSE;
91     }
92     return this;
93 }
94
95 DEFINE_THISCALL_WRAPPER(MSVCP_exception_copy_ctor,8)
96 exception* __thiscall MSVCP_exception_copy_ctor(exception *this, const exception *rhs)
97 {
98     TRACE("(%p,%p)\n", this, rhs);
99
100     if(!rhs->do_free) {
101         this->vtable = &MSVCP_exception_vtable;
102         this->name = rhs->name;
103         this->do_free = FALSE;
104     } else
105         MSVCP_exception_ctor(this, rhs->name);
106     TRACE("name = %s\n", this->name);
107     return this;
108 }
109
110 DEFINE_THISCALL_WRAPPER(MSVCP_exception_dtor,4)
111 void __thiscall MSVCP_exception_dtor(exception *this)
112 {
113     TRACE("(%p)\n", this);
114     this->vtable = &MSVCP_exception_vtable;
115     if(this->do_free)
116         free(this->name);
117 }
118
119 DEFINE_THISCALL_WRAPPER(MSVCP_exception_vector_dtor, 8)
120 void * __thiscall MSVCP_exception_vector_dtor(exception *this, unsigned int flags)
121 {
122     TRACE("%p %x\n", this, flags);
123     if(flags & 2) {
124         /* we have an array, with the number of elements stored before the first object */
125         INT_PTR i, *ptr = (INT_PTR *)this-1;
126
127         for(i=*ptr-1; i>=0; i--)
128             MSVCP_exception_dtor(this+i);
129         MSVCRT_operator_delete(ptr);
130     } else {
131         MSVCP_exception_dtor(this);
132         if(flags & 1)
133             MSVCRT_operator_delete(this);
134     }
135
136     return this;
137 }
138
139 DEFINE_RTTI_DATA0(exception, 0, ".?AVexception@std@@");
140 DEFINE_CXX_DATA0(exception, MSVCP_exception_dtor);
141
142 /* ?_Doraise@bad_alloc@std@@MBEXXZ */
143 /* ?_Doraise@bad_alloc@std@@MEBAXXZ */
144 /* ?_Doraise@logic_error@std@@MBEXXZ */
145 /* ?_Doraise@logic_error@std@@MEBAXXZ */
146 /* ?_Doraise@length_error@std@@MBEXXZ */
147 /* ?_Doraise@length_error@std@@MEBAXXZ */
148 /* ?_Doraise@out_of_range@std@@MBEXXZ */
149 /* ?_Doraise@out_of_range@std@@MEBAXXZ */
150 /* ?_Doraise@runtime_error@std@@MBEXXZ */
151 /* ?_Doraise@runtime_error@std@@MEBAXXZ */
152 DEFINE_THISCALL_WRAPPER(MSVCP_exception__Doraise, 4)
153 void __thiscall MSVCP_exception__Doraise(exception *this)
154 {
155     FIXME("(%p) stub\n", this);
156 }
157
158 DEFINE_THISCALL_WRAPPER(MSVCP_exception_what,4)
159 const char* __thiscall MSVCP_exception_what(exception * this)
160 {
161     TRACE("(%p) returning %s\n", this, this->name);
162     return this->name ? this->name : "Unknown exception";
163 }
164
165 /* bad_alloc class data */
166 typedef exception bad_alloc;
167
168 /* ??0bad_alloc@std@@QAE@PBD@Z */
169 /* ??0bad_alloc@std@@QEAA@PEBD@Z */
170 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_ctor, 8)
171 bad_alloc* __thiscall MSVCP_bad_alloc_ctor(bad_alloc *this, const char *name)
172 {
173     TRACE("%p %s\n", this, name);
174     MSVCP_exception_ctor(this, name);
175     this->vtable = &MSVCP_bad_alloc_vtable;
176     return this;
177 }
178
179 /* ??0bad_alloc@std@@QAE@XZ */
180 /* ??0bad_alloc@std@@QEAA@XZ */
181 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_default_ctor, 4)
182 bad_alloc* __thiscall MSVCP_bad_alloc_default_ctor(bad_alloc *this)
183 {
184     return MSVCP_bad_alloc_ctor(this, "bad allocation");
185 }
186
187 /* ??0bad_alloc@std@@QAE@ABV01@@Z */
188 /* ??0bad_alloc@std@@QEAA@AEBV01@@Z */
189 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_copy_ctor, 8)
190 bad_alloc* __thiscall MSVCP_bad_alloc_copy_ctor(bad_alloc *this, const bad_alloc *rhs)
191 {
192     TRACE("%p %p\n", this, rhs);
193     MSVCP_exception_copy_ctor(this, rhs);
194     this->vtable = &MSVCP_bad_alloc_vtable;
195     return this;
196 }
197
198 /* ??1bad_alloc@std@@UAE@XZ */
199 /* ??1bad_alloc@std@@UEAA@XZ */
200 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_dtor, 4)
201 void __thiscall MSVCP_bad_alloc_dtor(bad_alloc *this)
202 {
203     TRACE("%p\n", this);
204     MSVCP_exception_dtor(this);
205 }
206
207 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_vector_dtor, 8)
208 void * __thiscall MSVCP_bad_alloc_vector_dtor(bad_alloc *this, unsigned int flags)
209 {
210     TRACE("%p %x\n", this, flags);
211     if(flags & 2) {
212         /* we have an array, with the number of elements stored before the first object */
213         INT_PTR i, *ptr = (INT_PTR *)this-1;
214
215         for(i=*ptr-1; i>=0; i--)
216             MSVCP_bad_alloc_dtor(this+i);
217         MSVCRT_operator_delete(ptr);
218     } else {
219         MSVCP_bad_alloc_dtor(this);
220         if(flags & 1)
221             MSVCRT_operator_delete(this);
222     }
223
224     return this;
225 }
226
227 /* ??4bad_alloc@std@@QAEAAV01@ABV01@@Z */
228 /* ??4bad_alloc@std@@QEAAAEAV01@AEBV01@@Z */
229 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_assign, 8)
230 bad_alloc* __thiscall MSVCP_bad_alloc_assign(bad_alloc *this, const bad_alloc *assign)
231 {
232     MSVCP_bad_alloc_dtor(this);
233     return MSVCP_bad_alloc_copy_ctor(this, assign);
234 }
235
236 DEFINE_RTTI_DATA1(bad_alloc, 0, &exception_rtti_base_descriptor, ".?AVbad_alloc@std@@");
237 DEFINE_CXX_DATA1(bad_alloc, &exception_cxx_type_info, MSVCP_bad_alloc_dtor);
238
239 /* logic_error class data */
240 typedef struct {
241     exception e;
242     basic_string_char str;
243 } logic_error;
244
245 static logic_error* MSVCP_logic_error_ctor(
246         logic_error *this, const char *name)
247 {
248     TRACE("%p %s\n", this, name);
249     this->e.vtable = &MSVCP_logic_error_vtable;
250     this->e.name = NULL;
251     this->e.do_free = FALSE;
252     basic_string_char_ctor_cstr(&this->str, name);
253     return this;
254 }
255
256 /* ??0logic_error@std@@QAE@ABV01@@Z */
257 /* ??0logic_error@std@@QEAA@AEBV01@@Z */
258 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_copy_ctor, 8)
259 logic_error* __thiscall MSVCP_logic_error_copy_ctor(
260         logic_error *this, const logic_error *rhs)
261 {
262     TRACE("%p %p\n", this, rhs);
263     MSVCP_exception_copy_ctor(&this->e, &rhs->e);
264     basic_string_char_copy_ctor(&this->str, &rhs->str);
265     this->e.vtable = &MSVCP_logic_error_vtable;
266     return this;
267 }
268
269 /* ??0logic_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
270 /* ??0logic_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
271 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_ctor_bstr, 8)
272 logic_error* __thiscall MSVCP_logic_error_ctor_bstr(logic_error *this, const basic_string_char *str)
273 {
274     TRACE("(%p %p)\n", this, str);
275     return MSVCP_logic_error_ctor(this, basic_string_char_c_str(str));
276 }
277
278 /* ??1logic_error@std@@UAE@XZ */
279 /* ??1logic_error@std@@UEAA@XZ */
280 /* ??1length_error@std@@UAE@XZ */
281 /* ??1length_error@std@@UEAA@XZ */
282 /* ??1out_of_range@std@@UAE@XZ */
283 /* ??1out_of_range@std@@UEAA@XZ */
284 /* ??1runtime_error@std@@UAE@XZ */
285 /* ??1runtime_error@std@@UEAA@XZ */
286 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_dtor, 4)
287 void __thiscall MSVCP_logic_error_dtor(logic_error *this)
288 {
289     TRACE("%p\n", this);
290     MSVCP_exception_dtor(&this->e);
291     basic_string_char_dtor(&this->str);
292 }
293
294 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_vector_dtor, 8)
295 void* __thiscall MSVCP_logic_error_vector_dtor(
296         logic_error *this, unsigned int flags)
297 {
298     TRACE("%p %x\n", this, flags);
299     if(flags & 2) {
300         /* we have an array, with the number of elements stored before the first object */
301         INT_PTR i, *ptr = (INT_PTR *)this-1;
302
303         for(i=*ptr-1; i>=0; i--)
304             MSVCP_logic_error_dtor(this+i);
305         MSVCRT_operator_delete(ptr);
306     } else {
307         MSVCP_logic_error_dtor(this);
308         if(flags & 1)
309             MSVCRT_operator_delete(this);
310     }
311
312     return this;
313 }
314
315 /* ??4logic_error@std@@QAEAAV01@ABV01@@Z */
316 /* ??4logic_error@std@@QEAAAEAV01@AEBV01@@Z */
317 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_assign, 8)
318 logic_error* __thiscall MSVCP_logic_error_assign(logic_error *this, const logic_error *assign)
319 {
320     MSVCP_logic_error_dtor(this);
321     return MSVCP_logic_error_copy_ctor(this, assign);
322 }
323
324 /* ?what@logic_error@std@@UBEPBDXZ */
325 /* ?what@logic_error@std@@UEBAPEBDXZ */
326 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_what, 4)
327 const char* __thiscall MSVCP_logic_error_what(logic_error *this)
328 {
329     TRACE("%p\n", this);
330     return basic_string_char_c_str(&this->str);
331 }
332
333 DEFINE_RTTI_DATA1(logic_error, 0, &exception_rtti_base_descriptor, ".?AVlogic_error@std@@");
334 DEFINE_CXX_DATA1(logic_error, &exception_cxx_type_info, MSVCP_logic_error_dtor);
335
336 /* length_error class data */
337 typedef logic_error length_error;
338
339 static length_error* MSVCP_length_error_ctor(
340         length_error *this, const char *name)
341 {
342     TRACE("%p %s\n", this, name);
343     MSVCP_logic_error_ctor(this, name);
344     this->e.vtable = &MSVCP_length_error_vtable;
345     return this;
346 }
347
348 /* ??0length_error@std@@QAE@ABV01@@Z */
349 /* ??0length_error@std@@QEAA@AEBV01@@Z */
350 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_copy_ctor, 8)
351 length_error* __thiscall MSVCP_length_error_copy_ctor(
352         length_error *this, const length_error *rhs)
353 {
354     TRACE("%p %p\n", this, rhs);
355     MSVCP_logic_error_copy_ctor(this, rhs);
356     this->e.vtable = &MSVCP_length_error_vtable;
357     return this;
358 }
359
360 /* ??0length_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
361 /* ??0length_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
362 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_ctor_bstr, 8)
363 length_error* __thiscall MSVCP_length_error_ctor_bstr(length_error *this, const basic_string_char *str)
364 {
365         TRACE("(%p %p)\n", this, str);
366         return MSVCP_length_error_ctor(this, basic_string_char_c_str(str));
367 }
368
369 /* ??4length_error@std@@QAEAAV01@ABV01@@Z */
370 /* ??4length_error@std@@QEAAAEAV01@AEBV01@@Z */
371 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_assign, 8)
372 length_error* __thiscall MSVCP_length_error_assign(length_error *this, const length_error *assign)
373 {
374     MSVCP_logic_error_dtor(this);
375     return MSVCP_length_error_copy_ctor(this, assign);
376 }
377
378 DEFINE_RTTI_DATA2(length_error, 0, &logic_error_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AVlength_error@std@@");
379 DEFINE_CXX_DATA2(length_error, &logic_error_cxx_type_info, &exception_cxx_type_info, MSVCP_logic_error_dtor);
380
381 /* out_of_range class data */
382 typedef logic_error out_of_range;
383
384 static out_of_range* MSVCP_out_of_range_ctor(
385         out_of_range *this, const char *name)
386 {
387     TRACE("%p %s\n", this, name);
388     MSVCP_logic_error_ctor(this, name);
389     this->e.vtable = &MSVCP_out_of_range_vtable;
390     return this;
391 }
392
393 /* ??0out_of_range@std@@QAE@ABV01@@Z */
394 /* ??0out_of_range@std@@QEAA@AEBV01@@Z */
395 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_copy_ctor, 8)
396 out_of_range* __thiscall MSVCP_out_of_range_copy_ctor(
397         out_of_range *this, const out_of_range *rhs)
398 {
399     TRACE("%p %p\n", this, rhs);
400     MSVCP_logic_error_copy_ctor(this, rhs);
401     this->e.vtable = &MSVCP_out_of_range_vtable;
402     return this;
403 }
404
405 /* ??0out_of_range@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
406 /* ??0out_of_range@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
407 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_ctor_bstr, 8)
408 out_of_range* __thiscall MSVCP_out_of_range_ctor_bstr(out_of_range *this, const basic_string_char *str)
409 {
410     TRACE("(%p %p)\n", this, str);
411     return MSVCP_out_of_range_ctor(this, basic_string_char_c_str(str));
412 }
413
414 /* ??4out_of_range@std@@QAEAAV01@ABV01@@Z */
415 /* ??4out_of_range@std@@QEAAAEAV01@AEBV01@@Z */
416 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_assign, 8)
417 out_of_range* __thiscall MSVCP_out_of_range_assign(out_of_range *this, const out_of_range *assign)
418 {
419     MSVCP_logic_error_dtor(this);
420     return MSVCP_out_of_range_copy_ctor(this, assign);
421 }
422
423 DEFINE_RTTI_DATA2(out_of_range, 0, &logic_error_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AVout_of_range@std@@");
424 DEFINE_CXX_DATA2(out_of_range, &logic_error_cxx_type_info, &exception_cxx_type_info, MSVCP_logic_error_dtor);
425
426 /* invalid_argument class data */
427 typedef logic_error invalid_argument;
428
429 static invalid_argument* MSVCP_invalid_argument_ctor(
430         invalid_argument *this, const char *name)
431 {
432     TRACE("%p %s\n", this, name);
433     MSVCP_logic_error_ctor(this, name);
434     this->e.vtable = &MSVCP_invalid_argument_vtable;
435     return this;
436 }
437
438 DEFINE_THISCALL_WRAPPER(MSVCP_invalid_argument_copy_ctor, 8)
439 invalid_argument* __thiscall MSVCP_invalid_argument_copy_ctor(
440         invalid_argument *this, invalid_argument *rhs)
441 {
442     TRACE("%p %p\n", this, rhs);
443     MSVCP_logic_error_copy_ctor(this, rhs);
444     this->e.vtable = &MSVCP_invalid_argument_vtable;
445     return this;
446 }
447
448 DEFINE_RTTI_DATA2(invalid_argument, 0, &logic_error_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AVinvalid_argument@std@@");
449 DEFINE_CXX_DATA2(invalid_argument, &logic_error_cxx_type_info,  &exception_cxx_type_info, MSVCP_logic_error_dtor);
450
451 /* runtime_error class data */
452 typedef logic_error runtime_error;
453
454 static runtime_error* MSVCP_runtime_error_ctor(
455         runtime_error *this, const char *name)
456 {
457     TRACE("%p %s\n", this, name);
458     MSVCP_logic_error_ctor(this, name);
459     this->e.vtable = &MSVCP_runtime_error_vtable;
460     return this;
461 }
462
463 /* ??0runtime_error@std@@QAE@ABV01@@Z */
464 /* ??0runtime_error@std@@QEAA@AEBV01@@Z */
465 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_copy_ctor, 8)
466 runtime_error* __thiscall MSVCP_runtime_error_copy_ctor(
467         runtime_error *this, const runtime_error *rhs)
468 {
469     TRACE("%p %p\n", this, rhs);
470     MSVCP_logic_error_copy_ctor(this, rhs);
471     this->e.vtable = &MSVCP_runtime_error_vtable;
472     return this;
473 }
474
475 /* ??0runtime_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
476 /* ??0runtime_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
477 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_ctor_bstr, 8)
478 runtime_error* __thiscall MSVCP_runtime_error_ctor_bstr(runtime_error *this, const basic_string_char *str)
479 {
480     TRACE("(%p %p)\n", this, str);
481     return MSVCP_runtime_error_ctor(this, basic_string_char_c_str(str));
482 }
483
484 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_vector_dtor, 8)
485 void* __thiscall MSVCP_runtime_error_vector_dtor(
486         runtime_error *this, unsigned int flags)
487 {
488     TRACE("%p %x\n", this, flags);
489     return MSVCP_logic_error_vector_dtor(this, flags);
490 }
491
492 /* ??4runtime_error@std@@QAEAAV01@ABV01@@Z */
493 /* ??4runtime_error@std@@QEAAAEAV01@AEBV01@@Z */
494 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_assign, 8)
495 runtime_error* __thiscall MSVCP_runtime_error_assign(runtime_error *this, const runtime_error *assign)
496 {
497     MSVCP_logic_error_dtor(this);
498     return MSVCP_runtime_error_copy_ctor(this, assign);
499 }
500
501 DEFINE_RTTI_DATA1(runtime_error, 0, &exception_rtti_base_descriptor, ".?AVruntime_error@std@@");
502 DEFINE_CXX_DATA1(runtime_error, &exception_cxx_type_info, MSVCP_logic_error_dtor);
503
504 /* ?what@runtime_error@std@@UBEPBDXZ */
505 /* ?what@runtime_error@std@@UEBAPEBDXZ */
506 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_what, 4)
507 const char* __thiscall MSVCP_runtime_error_what(runtime_error *this)
508 {
509     TRACE("%p\n", this);
510     return basic_string_char_c_str(&this->str);
511 }
512
513 /* failure class data */
514 typedef runtime_error failure;
515
516 static failure* MSVCP_failure_ctor(
517         failure *this, const char *name)
518 {
519     TRACE("%p %s\n", this, name);
520     MSVCP_runtime_error_ctor(this, name);
521     this->e.vtable = &MSVCP_failure_vtable;
522     return this;
523 }
524
525 DEFINE_THISCALL_WRAPPER(MSVCP_failure_copy_ctor, 8)
526 failure* __thiscall MSVCP_failure_copy_ctor(
527         failure *this, failure *rhs)
528 {
529     TRACE("%p %p\n", this, rhs);
530     MSVCP_runtime_error_copy_ctor(this, rhs);
531     this->e.vtable = &MSVCP_failure_vtable;
532     return this;
533 }
534
535 DEFINE_THISCALL_WRAPPER(MSVCP_failure_dtor, 4)
536 void __thiscall MSVCP_failure_dtor(failure *this)
537 {
538     TRACE("%p\n", this);
539     MSVCP_logic_error_dtor(this);
540 }
541
542 DEFINE_THISCALL_WRAPPER(MSVCP_failure_vector_dtor, 8)
543 void* __thiscall MSVCP_failure_vector_dtor(
544         failure *this, unsigned int flags)
545 {
546     TRACE("%p %x\n", this, flags);
547     return MSVCP_runtime_error_vector_dtor(this, flags);
548 }
549
550 DEFINE_THISCALL_WRAPPER(MSVCP_failure_what, 4)
551 const char* __thiscall MSVCP_failure_what(failure *this)
552 {
553     TRACE("%p\n", this);
554     return MSVCP_runtime_error_what(this);
555 }
556
557 DEFINE_RTTI_DATA2(failure, 0, &runtime_error_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AVfailure@std@@");
558 DEFINE_CXX_DATA2(failure, &runtime_error_cxx_type_info, &exception_cxx_type_info, MSVCP_logic_error_dtor);
559
560 /* ?_Nomemory@std@@YAXXZ */
561 void __cdecl _Nomemory(void)
562 {
563     TRACE("()\n");
564     throw_exception(EXCEPTION_BAD_ALLOC, NULL);
565 }
566
567 #ifndef __GNUC__
568 void __asm_dummy_vtables(void) {
569 #endif
570     __ASM_VTABLE(type_info,
571             VTABLE_ADD_FUNC(MSVCP_type_info_vector_dtor));
572     __ASM_VTABLE(exception,
573             VTABLE_ADD_FUNC(MSVCP_exception_vector_dtor)
574             VTABLE_ADD_FUNC(MSVCP_exception_what)
575             VTABLE_ADD_FUNC(MSVCP_exception__Doraise));
576     __ASM_VTABLE(bad_alloc,
577             VTABLE_ADD_FUNC(MSVCP_bad_alloc_vector_dtor)
578             VTABLE_ADD_FUNC(MSVCP_exception_what)
579             VTABLE_ADD_FUNC(MSVCP_exception__Doraise));
580     __ASM_VTABLE(logic_error,
581             VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor)
582             VTABLE_ADD_FUNC(MSVCP_logic_error_what)
583             VTABLE_ADD_FUNC(MSVCP_exception__Doraise));
584     __ASM_VTABLE(length_error,
585             VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor)
586             VTABLE_ADD_FUNC(MSVCP_logic_error_what)
587             VTABLE_ADD_FUNC(MSVCP_exception__Doraise));
588     __ASM_VTABLE(out_of_range,
589             VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor)
590             VTABLE_ADD_FUNC(MSVCP_logic_error_what)
591             VTABLE_ADD_FUNC(MSVCP_exception__Doraise));
592     __ASM_VTABLE(invalid_argument,
593             VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor)
594             VTABLE_ADD_FUNC(MSVCP_logic_error_what)
595             VTABLE_ADD_FUNC(MSVCP_exception__Doraise));
596     __ASM_VTABLE(runtime_error,
597             VTABLE_ADD_FUNC(MSVCP_runtime_error_vector_dtor)
598             VTABLE_ADD_FUNC(MSVCP_runtime_error_what)
599             VTABLE_ADD_FUNC(MSVCP_exception__Doraise));
600     __ASM_VTABLE(failure,
601             VTABLE_ADD_FUNC(MSVCP_failure_vector_dtor)
602             VTABLE_ADD_FUNC(MSVCP_failure_what));
603 #ifndef __GNUC__
604 }
605 #endif
606
607 /* Internal: throws selected exception */
608 void throw_exception(exception_type et, const char *str)
609 {
610     switch(et) {
611     case EXCEPTION_RERAISE:
612         _CxxThrowException(NULL, NULL);
613     case EXCEPTION: {
614         exception e;
615         MSVCP_exception_ctor(&e, str);
616         _CxxThrowException(&e, &exception_cxx_type);
617     }
618     case EXCEPTION_BAD_ALLOC: {
619         bad_alloc e;
620         MSVCP_bad_alloc_ctor(&e, str);
621         _CxxThrowException(&e, &bad_alloc_cxx_type);
622     }
623     case EXCEPTION_LOGIC_ERROR: {
624         logic_error e;
625         MSVCP_logic_error_ctor(&e, str);
626         _CxxThrowException((exception*)&e, &logic_error_cxx_type);
627     }
628     case EXCEPTION_LENGTH_ERROR: {
629         length_error e;
630         MSVCP_length_error_ctor(&e, str);
631         _CxxThrowException((exception*)&e, &length_error_cxx_type);
632     }
633     case EXCEPTION_OUT_OF_RANGE: {
634         out_of_range e;
635         MSVCP_out_of_range_ctor(&e, str);
636         _CxxThrowException((exception*)&e, &out_of_range_cxx_type);
637     }
638     case EXCEPTION_INVALID_ARGUMENT: {
639         invalid_argument e;
640         MSVCP_invalid_argument_ctor(&e, str);
641         _CxxThrowException((exception*)&e, &invalid_argument_cxx_type);
642     }
643     case EXCEPTION_RUNTIME_ERROR: {
644         runtime_error e;
645         MSVCP_runtime_error_ctor(&e, str);
646         _CxxThrowException((exception*)&e, &runtime_error_cxx_type);
647     }
648     case EXCEPTION_FAILURE: {
649         failure e;
650         MSVCP_failure_ctor(&e, str);
651         _CxxThrowException((exception*)&e, &failure_cxx_type);
652     }
653     default:
654         ERR("exception type not handled: %d\n", et);
655     }
656 }
657
658 void init_exception(void *base)
659 {
660 #ifdef __x86_64__
661     init_type_info_rtti(base);
662     init_exception_rtti(base);
663     init_bad_alloc_rtti(base);
664     init_logic_error_rtti(base);
665     init_length_error_rtti(base);
666     init_out_of_range_rtti(base);
667     init_invalid_argument_rtti(base);
668     init_runtime_error_rtti(base);
669     init_failure_rtti(base);
670
671     init_exception_cxx(base);
672     init_bad_alloc_cxx(base);
673     init_logic_error_cxx(base);
674     init_length_error_cxx(base);
675     init_out_of_range_cxx(base);
676     init_invalid_argument_cxx(base);
677     init_runtime_error_cxx(base);
678     init_failure_cxx(base);
679 #endif
680 }