msvcp60: Copy source files from msvcp90.
[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 /* dlls/msvcrt/cppexcept.h */
31 typedef void (*cxx_copy_ctor)(void);
32
33 /* complete information about a C++ type */
34 typedef struct __cxx_type_info
35 {
36     UINT             flags;        /* flags (see CLASS_* flags below) */
37     const type_info *type_info;    /* C++ type info */
38     this_ptr_offsets offsets;      /* offsets for computing the this pointer */
39     unsigned int     size;         /* object size */
40     cxx_copy_ctor    copy_ctor;    /* copy constructor */
41 } cxx_type_info;
42 #define CLASS_IS_SIMPLE_TYPE          1
43 #define CLASS_HAS_VIRTUAL_BASE_CLASS  4
44
45 /* table of C++ types that apply for a given object */
46 typedef struct __cxx_type_info_table
47 {
48     UINT                 count;     /* number of types */
49     const cxx_type_info *info[3];   /* variable length, we declare it large enough for static RTTI */
50 } cxx_type_info_table;
51
52 /* type information for an exception object */
53 typedef struct __cxx_exception_type
54 {
55     UINT                       flags;            /* TYPE_FLAG flags */
56     void                     (*destructor)(void);/* exception object destructor */
57     void* /*cxx_exc_custom_handler*/ custom_handler;   /* custom handler for this exception */
58     const cxx_type_info_table *type_info_table;  /* list of types for this exception object */
59 } cxx_exception_type;
60
61 void WINAPI _CxxThrowException(exception*,const cxx_exception_type*);
62
63 /* vtables */
64 extern const vtable_ptr MSVCP_type_info_vtable;
65 extern const vtable_ptr MSVCP_exception_vtable;
66 /* ??_7bad_alloc@std@@6B@ */
67 extern const vtable_ptr MSVCP_bad_alloc_vtable;
68 /* ??_7logic_error@std@@6B@ */
69 extern const vtable_ptr MSVCP_logic_error_vtable;
70 /* ??_7length_error@std@@6B@ */
71 extern const vtable_ptr MSVCP_length_error_vtable;
72 /* ??_7out_of_range@std@@6B@ */
73 extern const vtable_ptr MSVCP_out_of_range_vtable;
74 extern const vtable_ptr MSVCP_invalid_argument_vtable;
75 /* ??_7runtime_error@std@@6B@ */
76 extern const vtable_ptr MSVCP_runtime_error_vtable;
77 extern const vtable_ptr MSVCP_failure_vtable;
78
79 static void MSVCP_type_info_dtor(type_info * _this)
80 {
81     free(_this->name);
82 }
83
84 DEFINE_THISCALL_WRAPPER(MSVCP_type_info_vector_dtor,8)
85 void * __thiscall MSVCP_type_info_vector_dtor(type_info * _this, unsigned int flags)
86 {
87     TRACE("(%p %x)\n", _this, flags);
88     if (flags & 2)
89     {
90         /* we have an array, with the number of elements stored before the first object */
91         INT_PTR i, *ptr = (INT_PTR *)_this - 1;
92
93         for (i = *ptr - 1; i >= 0; i--) MSVCP_type_info_dtor(_this + i);
94         MSVCRT_operator_delete(ptr);
95     }
96     else
97     {
98         MSVCP_type_info_dtor(_this);
99         if (flags & 1) MSVCRT_operator_delete(_this);
100     }
101     return _this;
102 }
103
104 DEFINE_RTTI_DATA0( type_info, 0, ".?AVtype_info@@" );
105
106 static exception* MSVCP_exception_ctor(exception *this, const char *name)
107 {
108     TRACE("(%p %s)\n", this, name);
109
110     this->vtable = &MSVCP_exception_vtable;
111     if(name) {
112         unsigned int name_len = strlen(name) + 1;
113         this->name = malloc(name_len);
114         memcpy(this->name, name, name_len);
115         this->do_free = TRUE;
116     } else {
117         this->name = NULL;
118         this->do_free = FALSE;
119     }
120     return this;
121 }
122
123 DEFINE_THISCALL_WRAPPER(MSVCP_exception_copy_ctor,8)
124 exception* __thiscall MSVCP_exception_copy_ctor(exception *this, const exception *rhs)
125 {
126     TRACE("(%p,%p)\n", this, rhs);
127
128     if(!rhs->do_free) {
129         this->vtable = &MSVCP_exception_vtable;
130         this->name = rhs->name;
131         this->do_free = FALSE;
132     } else
133         MSVCP_exception_ctor(this, rhs->name);
134     TRACE("name = %s\n", this->name);
135     return this;
136 }
137
138 DEFINE_THISCALL_WRAPPER(MSVCP_exception_dtor,4)
139 void __thiscall MSVCP_exception_dtor(exception *this)
140 {
141     TRACE("(%p)\n", this);
142     this->vtable = &MSVCP_exception_vtable;
143     if(this->do_free)
144         free(this->name);
145 }
146
147 DEFINE_THISCALL_WRAPPER(MSVCP_exception_vector_dtor, 8)
148 void * __thiscall MSVCP_exception_vector_dtor(exception *this, unsigned int flags)
149 {
150     TRACE("%p %x\n", this, flags);
151     if(flags & 2) {
152         /* we have an array, with the number of elements stored before the first object */
153         INT_PTR i, *ptr = (INT_PTR *)this-1;
154
155         for(i=*ptr-1; i>=0; i--)
156             MSVCP_exception_dtor(this+i);
157         MSVCRT_operator_delete(ptr);
158     } else {
159         MSVCP_exception_dtor(this);
160         if(flags & 1)
161             MSVCRT_operator_delete(this);
162     }
163
164     return this;
165 }
166
167 DEFINE_RTTI_DATA0(exception, 0, ".?AVexception@std@@");
168
169 /* ?_Doraise@bad_alloc@std@@MBEXXZ */
170 /* ?_Doraise@bad_alloc@std@@MEBAXXZ */
171 /* ?_Doraise@logic_error@std@@MBEXXZ */
172 /* ?_Doraise@logic_error@std@@MEBAXXZ */
173 /* ?_Doraise@length_error@std@@MBEXXZ */
174 /* ?_Doraise@length_error@std@@MEBAXXZ */
175 /* ?_Doraise@out_of_range@std@@MBEXXZ */
176 /* ?_Doraise@out_of_range@std@@MEBAXXZ */
177 /* ?_Doraise@runtime_error@std@@MBEXXZ */
178 /* ?_Doraise@runtime_error@std@@MEBAXXZ */
179 DEFINE_THISCALL_WRAPPER(MSVCP_exception__Doraise, 4)
180 void __thiscall MSVCP_exception__Doraise(exception *this)
181 {
182     FIXME("(%p) stub\n", this);
183 }
184
185 DEFINE_THISCALL_WRAPPER(MSVCP_exception_what,4)
186 const char* __thiscall MSVCP_exception_what(exception * this)
187 {
188     TRACE("(%p) returning %s\n", this, this->name);
189     return this->name ? this->name : "Unknown exception";
190 }
191
192 static const cxx_type_info exception_cxx_type_info = {
193     0,
194     &exception_type_info,
195     { 0, -1, 0 },
196     sizeof(exception),
197     (cxx_copy_ctor)THISCALL(MSVCP_exception_dtor)
198 };
199
200 static const cxx_type_info_table exception_cxx_type_table = {
201     1,
202     {
203         &exception_cxx_type_info,
204         NULL,
205         NULL
206     }
207 };
208
209 static const cxx_exception_type exception_cxx_type = {
210     0,
211     (cxx_copy_ctor)THISCALL(MSVCP_exception_copy_ctor),
212     NULL,
213     &exception_cxx_type_table
214 };
215
216 /* bad_alloc class data */
217 typedef exception bad_alloc;
218
219 /* ??0bad_alloc@std@@QAE@PBD@Z */
220 /* ??0bad_alloc@std@@QEAA@PEBD@Z */
221 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_ctor, 8)
222 bad_alloc* __thiscall MSVCP_bad_alloc_ctor(bad_alloc *this, const char *name)
223 {
224     TRACE("%p %s\n", this, name);
225     MSVCP_exception_ctor(this, name);
226     this->vtable = &MSVCP_bad_alloc_vtable;
227     return this;
228 }
229
230 /* ??0bad_alloc@std@@QAE@XZ */
231 /* ??0bad_alloc@std@@QEAA@XZ */
232 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_default_ctor, 4)
233 bad_alloc* __thiscall MSVCP_bad_alloc_default_ctor(bad_alloc *this)
234 {
235     return MSVCP_bad_alloc_ctor(this, "bad allocation");
236 }
237
238 /* ??0bad_alloc@std@@QAE@ABV01@@Z */
239 /* ??0bad_alloc@std@@QEAA@AEBV01@@Z */
240 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_copy_ctor, 8)
241 bad_alloc* __thiscall MSVCP_bad_alloc_copy_ctor(bad_alloc *this, const bad_alloc *rhs)
242 {
243     TRACE("%p %p\n", this, rhs);
244     MSVCP_exception_copy_ctor(this, rhs);
245     this->vtable = &MSVCP_bad_alloc_vtable;
246     return this;
247 }
248
249 /* ??1bad_alloc@std@@UAE@XZ */
250 /* ??1bad_alloc@std@@UEAA@XZ */
251 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_dtor, 4)
252 void __thiscall MSVCP_bad_alloc_dtor(bad_alloc *this)
253 {
254     TRACE("%p\n", this);
255     MSVCP_exception_dtor(this);
256 }
257
258 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_vector_dtor, 8)
259 void * __thiscall MSVCP_bad_alloc_vector_dtor(bad_alloc *this, unsigned int flags)
260 {
261     TRACE("%p %x\n", this, flags);
262     if(flags & 2) {
263         /* we have an array, with the number of elements stored before the first object */
264         INT_PTR i, *ptr = (INT_PTR *)this-1;
265
266         for(i=*ptr-1; i>=0; i--)
267             MSVCP_bad_alloc_dtor(this+i);
268         MSVCRT_operator_delete(ptr);
269     } else {
270         MSVCP_bad_alloc_dtor(this);
271         if(flags & 1)
272             MSVCRT_operator_delete(this);
273     }
274
275     return this;
276 }
277
278 /* ??4bad_alloc@std@@QAEAAV01@ABV01@@Z */
279 /* ??4bad_alloc@std@@QEAAAEAV01@AEBV01@@Z */
280 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_assign, 8)
281 bad_alloc* __thiscall MSVCP_bad_alloc_assign(bad_alloc *this, const bad_alloc *assign)
282 {
283     MSVCP_bad_alloc_dtor(this);
284     return MSVCP_bad_alloc_copy_ctor(this, assign);
285 }
286
287 DEFINE_RTTI_DATA1(bad_alloc, 0, &exception_rtti_base_descriptor, ".?AVbad_alloc@std@@");
288
289 static const cxx_type_info bad_alloc_cxx_type_info = {
290     0,
291     &bad_alloc_type_info,
292     { 0, -1, 0 },
293     sizeof(bad_alloc),
294     (cxx_copy_ctor)THISCALL(MSVCP_bad_alloc_copy_ctor)
295 };
296
297 static const cxx_type_info_table bad_alloc_cxx_type_table = {
298     2,
299     {
300         &bad_alloc_cxx_type_info,
301         &exception_cxx_type_info,
302         NULL
303     }
304 };
305
306 static const cxx_exception_type bad_alloc_cxx_type = {
307     0,
308     (cxx_copy_ctor)THISCALL(MSVCP_bad_alloc_dtor),
309     NULL,
310     &bad_alloc_cxx_type_table
311 };
312
313 /* logic_error class data */
314 typedef struct {
315     exception e;
316     basic_string_char str;
317 } logic_error;
318
319 static logic_error* MSVCP_logic_error_ctor(
320         logic_error *this, const char *name)
321 {
322     TRACE("%p %s\n", this, name);
323     this->e.vtable = &MSVCP_logic_error_vtable;
324     this->e.name = NULL;
325     this->e.do_free = FALSE;
326     basic_string_char_ctor_cstr(&this->str, name);
327     return this;
328 }
329
330 /* ??0logic_error@std@@QAE@ABV01@@Z */
331 /* ??0logic_error@std@@QEAA@AEBV01@@Z */
332 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_copy_ctor, 8)
333 logic_error* __thiscall MSVCP_logic_error_copy_ctor(
334         logic_error *this, const logic_error *rhs)
335 {
336     TRACE("%p %p\n", this, rhs);
337     MSVCP_exception_copy_ctor(&this->e, &rhs->e);
338     basic_string_char_copy_ctor(&this->str, &rhs->str);
339     this->e.vtable = &MSVCP_logic_error_vtable;
340     return this;
341 }
342
343 /* ??0logic_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
344 /* ??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)
347 {
348     TRACE("(%p %p)\n", this, str);
349     return MSVCP_logic_error_ctor(this, basic_string_char_c_str(str));
350 }
351
352 /* ??1logic_error@std@@UAE@XZ */
353 /* ??1logic_error@std@@UEAA@XZ */
354 /* ??1length_error@std@@UAE@XZ */
355 /* ??1length_error@std@@UEAA@XZ */
356 /* ??1out_of_range@std@@UAE@XZ */
357 /* ??1out_of_range@std@@UEAA@XZ */
358 /* ??1runtime_error@std@@UAE@XZ */
359 /* ??1runtime_error@std@@UEAA@XZ */
360 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_dtor, 4)
361 void __thiscall MSVCP_logic_error_dtor(logic_error *this)
362 {
363     TRACE("%p\n", this);
364     MSVCP_exception_dtor(&this->e);
365     basic_string_char_dtor(&this->str);
366 }
367
368 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_vector_dtor, 8)
369 void* __thiscall MSVCP_logic_error_vector_dtor(
370         logic_error *this, unsigned int flags)
371 {
372     TRACE("%p %x\n", this, flags);
373     if(flags & 2) {
374         /* we have an array, with the number of elements stored before the first object */
375         INT_PTR i, *ptr = (INT_PTR *)this-1;
376
377         for(i=*ptr-1; i>=0; i--)
378             MSVCP_logic_error_dtor(this+i);
379         MSVCRT_operator_delete(ptr);
380     } else {
381         MSVCP_logic_error_dtor(this);
382         if(flags & 1)
383             MSVCRT_operator_delete(this);
384     }
385
386     return this;
387 }
388
389 /* ??4logic_error@std@@QAEAAV01@ABV01@@Z */
390 /* ??4logic_error@std@@QEAAAEAV01@AEBV01@@Z */
391 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_assign, 8)
392 logic_error* __thiscall MSVCP_logic_error_assign(logic_error *this, const logic_error *assign)
393 {
394     MSVCP_logic_error_dtor(this);
395     return MSVCP_logic_error_copy_ctor(this, assign);
396 }
397
398 /* ?what@logic_error@std@@UBEPBDXZ */
399 /* ?what@logic_error@std@@UEBAPEBDXZ */
400 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_what, 4)
401 const char* __thiscall MSVCP_logic_error_what(logic_error *this)
402 {
403     TRACE("%p\n", this);
404     return basic_string_char_c_str(&this->str);
405 }
406
407 DEFINE_RTTI_DATA1(logic_error, 0, &exception_rtti_base_descriptor, ".?AVlogic_error@std@@");
408
409 static const cxx_type_info logic_error_cxx_type_info = {
410     0,
411     &logic_error_type_info,
412     { 0, -1, 0 },
413     sizeof(logic_error),
414     (cxx_copy_ctor)THISCALL(MSVCP_logic_error_copy_ctor)
415 };
416
417 static const cxx_type_info_table logic_error_cxx_type_table = {
418     2,
419     {
420         &logic_error_cxx_type_info,
421         &exception_cxx_type_info,
422         NULL
423     }
424 };
425
426 static const cxx_exception_type logic_error_cxx_type = {
427     0,
428     (cxx_copy_ctor)THISCALL(MSVCP_logic_error_dtor),
429     NULL,
430     &logic_error_cxx_type_table
431 };
432
433 /* length_error class data */
434 typedef logic_error length_error;
435
436 static length_error* MSVCP_length_error_ctor(
437         length_error *this, const char *name)
438 {
439     TRACE("%p %s\n", this, name);
440     MSVCP_logic_error_ctor(this, name);
441     this->e.vtable = &MSVCP_length_error_vtable;
442     return this;
443 }
444
445 /* ??0length_error@std@@QAE@ABV01@@Z */
446 /* ??0length_error@std@@QEAA@AEBV01@@Z */
447 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_copy_ctor, 8)
448 length_error* __thiscall MSVCP_length_error_copy_ctor(
449         length_error *this, const length_error *rhs)
450 {
451     TRACE("%p %p\n", this, rhs);
452     MSVCP_logic_error_copy_ctor(this, rhs);
453     this->e.vtable = &MSVCP_length_error_vtable;
454     return this;
455 }
456
457 /* ??0length_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
458 /* ??0length_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
459 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_ctor_bstr, 8)
460 length_error* __thiscall MSVCP_length_error_ctor_bstr(length_error *this, const basic_string_char *str)
461 {
462         TRACE("(%p %p)\n", this, str);
463         return MSVCP_length_error_ctor(this, basic_string_char_c_str(str));
464 }
465
466 /* ??4length_error@std@@QAEAAV01@ABV01@@Z */
467 /* ??4length_error@std@@QEAAAEAV01@AEBV01@@Z */
468 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_assign, 8)
469 length_error* __thiscall MSVCP_length_error_assign(length_error *this, const length_error *assign)
470 {
471     MSVCP_logic_error_dtor(this);
472     return MSVCP_length_error_copy_ctor(this, assign);
473 }
474
475 DEFINE_RTTI_DATA2(length_error, 0, &logic_error_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AVlength_error@std@@");
476
477 static const cxx_type_info length_error_cxx_type_info = {
478     0,
479     &length_error_type_info,
480     { 0, -1, 0 },
481     sizeof(length_error),
482     (cxx_copy_ctor)THISCALL(MSVCP_length_error_copy_ctor)
483 };
484
485 static const cxx_type_info_table length_error_cxx_type_table = {
486     3,
487     {
488         &length_error_cxx_type_info,
489         &logic_error_cxx_type_info,
490         &exception_cxx_type_info
491     }
492 };
493
494 static const cxx_exception_type length_error_cxx_type = {
495     0,
496     (cxx_copy_ctor)THISCALL(MSVCP_logic_error_dtor),
497     NULL,
498     &length_error_cxx_type_table
499 };
500
501 /* out_of_range class data */
502 typedef logic_error out_of_range;
503
504 static out_of_range* MSVCP_out_of_range_ctor(
505         out_of_range *this, const char *name)
506 {
507     TRACE("%p %s\n", this, name);
508     MSVCP_logic_error_ctor(this, name);
509     this->e.vtable = &MSVCP_out_of_range_vtable;
510     return this;
511 }
512
513 /* ??0out_of_range@std@@QAE@ABV01@@Z */
514 /* ??0out_of_range@std@@QEAA@AEBV01@@Z */
515 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_copy_ctor, 8)
516 out_of_range* __thiscall MSVCP_out_of_range_copy_ctor(
517         out_of_range *this, const out_of_range *rhs)
518 {
519     TRACE("%p %p\n", this, rhs);
520     MSVCP_logic_error_copy_ctor(this, rhs);
521     this->e.vtable = &MSVCP_out_of_range_vtable;
522     return this;
523 }
524
525 /* ??0out_of_range@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
526 /* ??0out_of_range@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
527 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_ctor_bstr, 8)
528 out_of_range* __thiscall MSVCP_out_of_range_ctor_bstr(out_of_range *this, const basic_string_char *str)
529 {
530     TRACE("(%p %p)\n", this, str);
531     return MSVCP_out_of_range_ctor(this, basic_string_char_c_str(str));
532 }
533
534 /* ??4out_of_range@std@@QAEAAV01@ABV01@@Z */
535 /* ??4out_of_range@std@@QEAAAEAV01@AEBV01@@Z */
536 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_assign, 8)
537 out_of_range* __thiscall MSVCP_out_of_range_assign(out_of_range *this, const out_of_range *assign)
538 {
539     MSVCP_logic_error_dtor(this);
540     return MSVCP_out_of_range_copy_ctor(this, assign);
541 }
542
543 DEFINE_RTTI_DATA2(out_of_range, 0, &logic_error_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AVout_of_range@std@@");
544
545 static const cxx_type_info out_of_range_cxx_type_info = {
546     0,
547     &out_of_range_type_info,
548     { 0, -1, 0 },
549     sizeof(out_of_range),
550     (cxx_copy_ctor)THISCALL(MSVCP_out_of_range_copy_ctor)
551 };
552
553 static const cxx_type_info_table out_of_range_cxx_type_table = {
554     3,
555     {
556         &out_of_range_cxx_type_info,
557         &logic_error_cxx_type_info,
558         &exception_cxx_type_info
559     }
560 };
561
562 static const cxx_exception_type out_of_range_cxx_type = {
563     0,
564     (cxx_copy_ctor)THISCALL(MSVCP_logic_error_dtor),
565     NULL,
566     &out_of_range_cxx_type_table
567 };
568
569 /* invalid_argument class data */
570 typedef logic_error invalid_argument;
571
572 static invalid_argument* MSVCP_invalid_argument_ctor(
573         invalid_argument *this, const char *name)
574 {
575     TRACE("%p %s\n", this, name);
576     MSVCP_logic_error_ctor(this, name);
577     this->e.vtable = &MSVCP_invalid_argument_vtable;
578     return this;
579 }
580
581 DEFINE_THISCALL_WRAPPER(MSVCP_invalid_argument_copy_ctor, 8)
582 invalid_argument* __thiscall MSVCP_invalid_argument_copy_ctor(
583         invalid_argument *this, invalid_argument *rhs)
584 {
585     TRACE("%p %p\n", this, rhs);
586     MSVCP_logic_error_copy_ctor(this, rhs);
587     this->e.vtable = &MSVCP_invalid_argument_vtable;
588     return this;
589 }
590
591 DEFINE_RTTI_DATA2(invalid_argument, 0, &logic_error_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AVinvalid_argument@std@@");
592
593 static const cxx_type_info invalid_argument_cxx_type_info = {
594     0,
595     &invalid_argument_type_info,
596     { 0, -1, 0 },
597     sizeof(invalid_argument),
598     (cxx_copy_ctor)THISCALL(MSVCP_invalid_argument_copy_ctor)
599 };
600
601 static const cxx_type_info_table invalid_argument_cxx_type_table = {
602     3,
603     {
604         &invalid_argument_cxx_type_info,
605         &logic_error_cxx_type_info,
606         &exception_cxx_type_info
607     }
608 };
609
610 static const cxx_exception_type invalid_argument_cxx_type = {
611     0,
612     (cxx_copy_ctor)THISCALL(MSVCP_logic_error_dtor),
613     NULL,
614     &invalid_argument_cxx_type_table
615 };
616
617 /* runtime_error class data */
618 typedef logic_error runtime_error;
619
620 static runtime_error* MSVCP_runtime_error_ctor(
621         runtime_error *this, const char *name)
622 {
623     TRACE("%p %s\n", this, name);
624     MSVCP_logic_error_ctor(this, name);
625     this->e.vtable = &MSVCP_runtime_error_vtable;
626     return this;
627 }
628
629 /* ??0runtime_error@std@@QAE@ABV01@@Z */
630 /* ??0runtime_error@std@@QEAA@AEBV01@@Z */
631 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_copy_ctor, 8)
632 runtime_error* __thiscall MSVCP_runtime_error_copy_ctor(
633         runtime_error *this, const runtime_error *rhs)
634 {
635     TRACE("%p %p\n", this, rhs);
636     MSVCP_logic_error_copy_ctor(this, rhs);
637     this->e.vtable = &MSVCP_runtime_error_vtable;
638     return this;
639 }
640
641 /* ??0runtime_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
642 /* ??0runtime_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
643 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_ctor_bstr, 8)
644 runtime_error* __thiscall MSVCP_runtime_error_ctor_bstr(runtime_error *this, const basic_string_char *str)
645 {
646     TRACE("(%p %p)\n", this, str);
647     return MSVCP_runtime_error_ctor(this, basic_string_char_c_str(str));
648 }
649
650 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_vector_dtor, 8)
651 void* __thiscall MSVCP_runtime_error_vector_dtor(
652         runtime_error *this, unsigned int flags)
653 {
654     TRACE("%p %x\n", this, flags);
655     return MSVCP_logic_error_vector_dtor(this, flags);
656 }
657
658 /* ??4runtime_error@std@@QAEAAV01@ABV01@@Z */
659 /* ??4runtime_error@std@@QEAAAEAV01@AEBV01@@Z */
660 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_assign, 8)
661 runtime_error* __thiscall MSVCP_runtime_error_assign(runtime_error *this, const runtime_error *assign)
662 {
663     MSVCP_logic_error_dtor(this);
664     return MSVCP_runtime_error_copy_ctor(this, assign);
665 }
666
667 DEFINE_RTTI_DATA1(runtime_error, 0, &exception_rtti_base_descriptor, ".?AVruntime_error@std@@");
668
669 static const cxx_type_info runtime_error_cxx_type_info = {
670     0,
671     &runtime_error_type_info,
672     { 0, -1, 0 },
673     sizeof(runtime_error),
674     (cxx_copy_ctor)THISCALL(MSVCP_runtime_error_copy_ctor)
675 };
676
677 static const cxx_type_info_table runtime_error_cxx_type_table = {
678     2,
679     {
680         &runtime_error_cxx_type_info,
681         &exception_cxx_type_info,
682         NULL
683     }
684 };
685
686 static const cxx_exception_type runtime_error_cxx_type = {
687     0,
688     (cxx_copy_ctor)THISCALL(MSVCP_logic_error_dtor),
689     NULL,
690     &runtime_error_cxx_type_table
691 };
692
693 /* ?what@runtime_error@std@@UBEPBDXZ */
694 /* ?what@runtime_error@std@@UEBAPEBDXZ */
695 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_what, 4)
696 const char* __thiscall MSVCP_runtime_error_what(runtime_error *this)
697 {
698     TRACE("%p\n", this);
699     return basic_string_char_c_str(&this->str);
700 }
701
702 /* failure class data */
703 typedef runtime_error failure;
704
705 static failure* MSVCP_failure_ctor(
706         failure *this, const char *name)
707 {
708     TRACE("%p %s\n", this, name);
709     MSVCP_runtime_error_ctor(this, name);
710     this->e.vtable = &MSVCP_failure_vtable;
711     return this;
712 }
713
714 DEFINE_THISCALL_WRAPPER(MSVCP_failure_copy_ctor, 8)
715 failure* __thiscall MSVCP_failure_copy_ctor(
716         failure *this, failure *rhs)
717 {
718     TRACE("%p %p\n", this, rhs);
719     MSVCP_runtime_error_copy_ctor(this, rhs);
720     this->e.vtable = &MSVCP_failure_vtable;
721     return this;
722 }
723
724 DEFINE_THISCALL_WRAPPER(MSVCP_failure_dtor, 4)
725 void __thiscall MSVCP_failure_dtor(failure *this)
726 {
727     TRACE("%p\n", this);
728     MSVCP_logic_error_dtor(this);
729 }
730
731 DEFINE_THISCALL_WRAPPER(MSVCP_failure_vector_dtor, 8)
732 void* __thiscall MSVCP_failure_vector_dtor(
733         failure *this, unsigned int flags)
734 {
735     TRACE("%p %x\n", this, flags);
736     return MSVCP_runtime_error_vector_dtor(this, flags);
737 }
738
739 DEFINE_THISCALL_WRAPPER(MSVCP_failure_what, 4)
740 const char* __thiscall MSVCP_failure_what(failure *this)
741 {
742     TRACE("%p\n", this);
743     return MSVCP_runtime_error_what(this);
744 }
745
746 DEFINE_RTTI_DATA2(failure, 0, &runtime_error_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AVfailure@std@@");
747
748 static const cxx_type_info failure_cxx_type_info = {
749     0,
750     &failure_type_info,
751     { 0, -1, 0 },
752     sizeof(failure),
753     (cxx_copy_ctor)THISCALL(MSVCP_failure_copy_ctor)
754 };
755
756 static const cxx_type_info_table failure_cxx_type_table = {
757     3,
758     {
759         &failure_cxx_type_info,
760         &runtime_error_cxx_type_info,
761         &exception_cxx_type_info
762     }
763 };
764
765 static const cxx_exception_type failure_cxx_type = {
766     0,
767     (cxx_copy_ctor)THISCALL(MSVCP_failure_dtor),
768     NULL,
769     &failure_cxx_type_table
770 };
771
772 #ifndef __GNUC__
773 void __asm_dummy_vtables(void) {
774 #endif
775     __ASM_VTABLE(type_info,
776             VTABLE_ADD_FUNC(MSVCP_type_info_vector_dtor));
777     __ASM_VTABLE(exception,
778             VTABLE_ADD_FUNC(MSVCP_exception_vector_dtor)
779             VTABLE_ADD_FUNC(MSVCP_exception_what)
780             VTABLE_ADD_FUNC(MSVCP_exception__Doraise));
781     __ASM_VTABLE(bad_alloc,
782             VTABLE_ADD_FUNC(MSVCP_bad_alloc_vector_dtor)
783             VTABLE_ADD_FUNC(MSVCP_exception_what)
784             VTABLE_ADD_FUNC(MSVCP_exception__Doraise));
785     __ASM_VTABLE(logic_error,
786             VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor)
787             VTABLE_ADD_FUNC(MSVCP_logic_error_what)
788             VTABLE_ADD_FUNC(MSVCP_exception__Doraise));
789     __ASM_VTABLE(length_error,
790             VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor)
791             VTABLE_ADD_FUNC(MSVCP_logic_error_what)
792             VTABLE_ADD_FUNC(MSVCP_exception__Doraise));
793     __ASM_VTABLE(out_of_range,
794             VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor)
795             VTABLE_ADD_FUNC(MSVCP_logic_error_what)
796             VTABLE_ADD_FUNC(MSVCP_exception__Doraise));
797     __ASM_VTABLE(invalid_argument,
798             VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor)
799             VTABLE_ADD_FUNC(MSVCP_logic_error_what)
800             VTABLE_ADD_FUNC(MSVCP_exception__Doraise));
801     __ASM_VTABLE(runtime_error,
802             VTABLE_ADD_FUNC(MSVCP_runtime_error_vector_dtor)
803             VTABLE_ADD_FUNC(MSVCP_runtime_error_what)
804             VTABLE_ADD_FUNC(MSVCP_exception__Doraise));
805     __ASM_VTABLE(failure,
806             VTABLE_ADD_FUNC(MSVCP_failure_vector_dtor)
807             VTABLE_ADD_FUNC(MSVCP_failure_what));
808 #ifndef __GNUC__
809 }
810 #endif
811
812 /* Internal: throws selected exception */
813 void throw_exception(exception_type et, const char *str)
814 {
815     switch(et) {
816     case EXCEPTION_RERAISE:
817         _CxxThrowException(NULL, NULL);
818     case EXCEPTION: {
819         exception e;
820         MSVCP_exception_ctor(&e, str);
821         _CxxThrowException(&e, &exception_cxx_type);
822     }
823     case EXCEPTION_BAD_ALLOC: {
824         bad_alloc e;
825         MSVCP_bad_alloc_ctor(&e, str);
826         _CxxThrowException(&e, &bad_alloc_cxx_type);
827     }
828     case EXCEPTION_LOGIC_ERROR: {
829         logic_error e;
830         MSVCP_logic_error_ctor(&e, str);
831         _CxxThrowException((exception*)&e, &logic_error_cxx_type);
832     }
833     case EXCEPTION_LENGTH_ERROR: {
834         length_error e;
835         MSVCP_length_error_ctor(&e, str);
836         _CxxThrowException((exception*)&e, &length_error_cxx_type);
837     }
838     case EXCEPTION_OUT_OF_RANGE: {
839         out_of_range e;
840         MSVCP_out_of_range_ctor(&e, str);
841         _CxxThrowException((exception*)&e, &out_of_range_cxx_type);
842     }
843     case EXCEPTION_INVALID_ARGUMENT: {
844         invalid_argument e;
845         MSVCP_invalid_argument_ctor(&e, str);
846         _CxxThrowException((exception*)&e, &invalid_argument_cxx_type);
847     }
848     case EXCEPTION_RUNTIME_ERROR: {
849         runtime_error e;
850         MSVCP_runtime_error_ctor(&e, str);
851         _CxxThrowException((exception*)&e, &runtime_error_cxx_type);
852     }
853     case EXCEPTION_FAILURE: {
854         failure e;
855         MSVCP_failure_ctor(&e, str);
856         _CxxThrowException((exception*)&e, &failure_cxx_type);
857     }
858     default:
859         ERR("exception type not handled: %d\n", et);
860     }
861 }
862
863 void init_exception(void *base)
864 {
865 #ifdef __x86_64__
866     init_type_info_rtti(base);
867     init_exception_rtti(base);
868     init_bad_alloc_rtti(base);
869     init_logic_error_rtti(base);
870     init_length_error_rtti(base);
871     init_out_of_range_rtti(base);
872     init_invalid_argument_rtti(base);
873     init_runtime_error_rtti(base);
874     init_failure_rtti(base);
875 #endif
876 }