po: Update French translation.
[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(msvcp90);
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
78 static void MSVCP_type_info_dtor(type_info * _this)
79 {
80     free(_this->name);
81 }
82
83 DEFINE_THISCALL_WRAPPER(MSVCP_type_info_vector_dtor,8)
84 void * __thiscall MSVCP_type_info_vector_dtor(type_info * _this, unsigned int flags)
85 {
86     TRACE("(%p %x)\n", _this, flags);
87     if (flags & 2)
88     {
89         /* we have an array, with the number of elements stored before the first object */
90         int i, *ptr = (int *)_this - 1;
91
92         for (i = *ptr - 1; i >= 0; i--) MSVCP_type_info_dtor(_this + i);
93         MSVCRT_operator_delete(ptr);
94     }
95     else
96     {
97         MSVCP_type_info_dtor(_this);
98         if (flags & 1) MSVCRT_operator_delete(_this);
99     }
100     return _this;
101 }
102
103 DEFINE_RTTI_DATA( type_info, 0, 0, NULL, NULL, NULL, ".?AVtype_info@@" );
104
105 DEFINE_THISCALL_WRAPPER(MSVCP_exception_ctor, 8)
106 exception* __thiscall 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 i, *ptr = (int *)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_DATA(exception, 0, 0, NULL, NULL, NULL, ".?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 i, *ptr = (int *)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_DATA(bad_alloc, 0, 1, &exception_rtti_base_descriptor, NULL, NULL, ".?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 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_ctor, 8)
320 logic_error* __thiscall MSVCP_logic_error_ctor(
321         logic_error *this, const char *name)
322 {
323     TRACE("%p %s\n", this, name);
324     this->e.vtable = &MSVCP_logic_error_vtable;
325     this->e.name = NULL;
326     this->e.do_free = FALSE;
327     MSVCP_basic_string_char_ctor_cstr(&this->str, name);
328     return this;
329 }
330
331 /* ??0logic_error@std@@QAE@ABV01@@Z */
332 /* ??0logic_error@std@@QEAA@AEBV01@@Z */
333 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_copy_ctor, 8)
334 logic_error* __thiscall MSVCP_logic_error_copy_ctor(
335         logic_error *this, const logic_error *rhs)
336 {
337     TRACE("%p %p\n", this, rhs);
338     MSVCP_exception_copy_ctor(&this->e, &rhs->e);
339     MSVCP_basic_string_char_copy_ctor(&this->str, &rhs->str);
340     this->e.vtable = &MSVCP_logic_error_vtable;
341     return this;
342 }
343
344 /* ??0logic_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
345 /* ??0logic_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
346 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_ctor_bstr, 8)
347 logic_error* __thiscall MSVCP_logic_error_ctor_bstr(logic_error *this, const basic_string_char *str)
348 {
349     TRACE("(%p %p)\n", this, str);
350     return MSVCP_logic_error_ctor(this, MSVCP_basic_string_char_c_str(str));
351 }
352
353 /* ??1logic_error@std@@UAE@XZ */
354 /* ??1logic_error@std@@UEAA@XZ */
355 /* ??1length_error@std@@UAE@XZ */
356 /* ??1length_error@std@@UEAA@XZ */
357 /* ??1out_of_range@std@@UAE@XZ */
358 /* ??1out_of_range@std@@UEAA@XZ */
359 /* ??1runtime_error@std@@UAE@XZ */
360 /* ??1runtime_error@std@@UEAA@XZ */
361 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_dtor, 4)
362 void __thiscall MSVCP_logic_error_dtor(logic_error *this)
363 {
364     TRACE("%p\n", this);
365     MSVCP_exception_dtor(&this->e);
366     MSVCP_basic_string_char_dtor(&this->str);
367 }
368
369 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_vector_dtor, 8)
370 void* __thiscall MSVCP_logic_error_vector_dtor(
371         logic_error *this, unsigned int flags)
372 {
373     TRACE("%p %x\n", this, flags);
374     if(flags & 2) {
375         /* we have an array, with the number of elements stored before the first object */
376         int i, *ptr = (int *)this-1;
377
378         for(i=*ptr-1; i>=0; i--)
379             MSVCP_logic_error_dtor(this+i);
380         MSVCRT_operator_delete(ptr);
381     } else {
382         MSVCP_logic_error_dtor(this);
383         if(flags & 1)
384             MSVCRT_operator_delete(this);
385     }
386
387     return this;
388 }
389
390 /* ??4logic_error@std@@QAEAAV01@ABV01@@Z */
391 /* ??4logic_error@std@@QEAAAEAV01@AEBV01@@Z */
392 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_assign, 8)
393 logic_error* __thiscall MSVCP_logic_error_assign(logic_error *this, const logic_error *assign)
394 {
395     MSVCP_logic_error_dtor(this);
396     return MSVCP_logic_error_copy_ctor(this, assign);
397 }
398
399 /* ?what@logic_error@std@@UBEPBDXZ */
400 /* ?what@logic_error@std@@UEBAPEBDXZ */
401 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_what, 4)
402 const char* __thiscall MSVCP_logic_error_what(logic_error *this)
403 {
404     TRACE("%p\n", this);
405     return MSVCP_basic_string_char_c_str(&this->str);
406 }
407
408 DEFINE_RTTI_DATA(logic_error, 0, 1, &exception_rtti_base_descriptor, NULL, NULL, ".?AVlogic_error@std@@");
409
410 static const cxx_type_info logic_error_cxx_type_info = {
411     0,
412     &logic_error_type_info,
413     { 0, -1, 0 },
414     sizeof(logic_error),
415     (cxx_copy_ctor)THISCALL(MSVCP_logic_error_copy_ctor)
416 };
417
418 static const cxx_type_info_table logic_error_cxx_type_table = {
419     2,
420     {
421         &logic_error_cxx_type_info,
422         &exception_cxx_type_info,
423         NULL
424     }
425 };
426
427 static const cxx_exception_type logic_error_cxx_type = {
428     0,
429     (cxx_copy_ctor)THISCALL(MSVCP_logic_error_dtor),
430     NULL,
431     &logic_error_cxx_type_table
432 };
433
434 /* length_error class data */
435 typedef logic_error length_error;
436
437 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_ctor, 8)
438 length_error* __thiscall MSVCP_length_error_ctor(
439         length_error *this, const char *name)
440 {
441     TRACE("%p %s\n", this, name);
442     MSVCP_logic_error_ctor(this, name);
443     this->e.vtable = &MSVCP_length_error_vtable;
444     return this;
445 }
446
447 /* ??0length_error@std@@QAE@ABV01@@Z */
448 /* ??0length_error@std@@QEAA@AEBV01@@Z */
449 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_copy_ctor, 8)
450 length_error* __thiscall MSVCP_length_error_copy_ctor(
451         length_error *this, const length_error *rhs)
452 {
453     TRACE("%p %p\n", this, rhs);
454     MSVCP_logic_error_copy_ctor(this, rhs);
455     this->e.vtable = &MSVCP_length_error_vtable;
456     return this;
457 }
458
459 /* ??0length_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
460 /* ??0length_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
461 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_ctor_bstr, 8)
462 length_error* __thiscall MSVCP_length_error_ctor_bstr(length_error *this, const basic_string_char *str)
463 {
464         TRACE("(%p %p)\n", this, str);
465         return MSVCP_length_error_ctor(this, MSVCP_basic_string_char_c_str(str));
466 }
467
468 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_vector_dtor, 8)
469 void* __thiscall MSVCP_length_error_vector_dtor(
470         length_error *this, unsigned int flags)
471 {
472     TRACE("%p %x\n", this, flags);
473     return MSVCP_logic_error_vector_dtor(this, flags);
474 }
475
476 /* ??4length_error@std@@QAEAAV01@ABV01@@Z */
477 /* ??4length_error@std@@QEAAAEAV01@AEBV01@@Z */
478 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_assign, 8)
479 length_error* __thiscall MSVCP_length_error_assign(length_error *this, const length_error *assign)
480 {
481     MSVCP_logic_error_dtor(this);
482     return MSVCP_length_error_copy_ctor(this, assign);
483 }
484
485 DEFINE_RTTI_DATA(length_error, 0, 2, &logic_error_rtti_base_descriptor, &exception_rtti_base_descriptor, NULL, ".?AVlength_error@std@@");
486
487 static const cxx_type_info length_error_cxx_type_info = {
488     0,
489     &length_error_type_info,
490     { 0, -1, 0 },
491     sizeof(length_error),
492     (cxx_copy_ctor)THISCALL(MSVCP_length_error_copy_ctor)
493 };
494
495 static const cxx_type_info_table length_error_cxx_type_table = {
496     3,
497     {
498         &length_error_cxx_type_info,
499         &logic_error_cxx_type_info,
500         &exception_cxx_type_info
501     }
502 };
503
504 static const cxx_exception_type length_error_cxx_type = {
505     0,
506     (cxx_copy_ctor)THISCALL(MSVCP_logic_error_dtor),
507     NULL,
508     &length_error_cxx_type_table
509 };
510
511 /* out_of_range class data */
512 typedef logic_error out_of_range;
513
514 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_ctor, 8)
515 out_of_range* __thiscall MSVCP_out_of_range_ctor(
516         out_of_range *this, const char *name)
517 {
518     TRACE("%p %s\n", this, name);
519     MSVCP_logic_error_ctor(this, name);
520     this->e.vtable = &MSVCP_out_of_range_vtable;
521     return this;
522 }
523
524 /* ??0out_of_range@std@@QAE@ABV01@@Z */
525 /* ??0out_of_range@std@@QEAA@AEBV01@@Z */
526 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_copy_ctor, 8)
527 out_of_range* __thiscall MSVCP_out_of_range_copy_ctor(
528         out_of_range *this, const out_of_range *rhs)
529 {
530     TRACE("%p %p\n", this, rhs);
531     MSVCP_logic_error_copy_ctor(this, rhs);
532     this->e.vtable = &MSVCP_out_of_range_vtable;
533     return this;
534 }
535
536 /* ??0out_of_range@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
537 /* ??0out_of_range@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
538 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_ctor_bstr, 8)
539 out_of_range* __thiscall MSVCP_out_of_range_ctor_bstr(out_of_range *this, const basic_string_char *str)
540 {
541     TRACE("(%p %p)\n", this, str);
542     return MSVCP_out_of_range_ctor(this, MSVCP_basic_string_char_c_str(str));
543 }
544
545 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_vector_dtor, 8)
546 void* __thiscall MSVCP_out_of_range_vector_dtor(
547         out_of_range *this, unsigned int flags)
548 {
549     TRACE("%p %x\n", this, flags);
550     return MSVCP_logic_error_vector_dtor(this, flags);
551 }
552
553 /* ??4out_of_range@std@@QAEAAV01@ABV01@@Z */
554 /* ??4out_of_range@std@@QEAAAEAV01@AEBV01@@Z */
555 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_assign, 8)
556 out_of_range* __thiscall MSVCP_out_of_range_assign(out_of_range *this, const out_of_range *assign)
557 {
558     MSVCP_logic_error_dtor(this);
559     return MSVCP_out_of_range_copy_ctor(this, assign);
560 }
561
562 DEFINE_RTTI_DATA(out_of_range, 0, 2, &logic_error_rtti_base_descriptor, &exception_rtti_base_descriptor, NULL, ".?AVout_of_range@std@@");
563
564 static const cxx_type_info out_of_range_cxx_type_info = {
565     0,
566     &out_of_range_type_info,
567     { 0, -1, 0 },
568     sizeof(out_of_range),
569     (cxx_copy_ctor)THISCALL(MSVCP_out_of_range_copy_ctor)
570 };
571
572 static const cxx_type_info_table out_of_range_cxx_type_table = {
573     3,
574     {
575         &out_of_range_cxx_type_info,
576         &logic_error_cxx_type_info,
577         &exception_cxx_type_info
578     }
579 };
580
581 static const cxx_exception_type out_of_range_cxx_type = {
582     0,
583     (cxx_copy_ctor)THISCALL(MSVCP_logic_error_dtor),
584     NULL,
585     &out_of_range_cxx_type_table
586 };
587
588 /* invalid_argument class data */
589 typedef logic_error invalid_argument;
590
591 DEFINE_THISCALL_WRAPPER(MSVCP_invalid_argument_ctor, 8)
592 invalid_argument* __thiscall MSVCP_invalid_argument_ctor(
593         invalid_argument *this, const char *name)
594 {
595     TRACE("%p %s\n", this, name);
596     MSVCP_logic_error_ctor(this, name);
597     this->e.vtable = &MSVCP_invalid_argument_vtable;
598     return this;
599 }
600
601 DEFINE_THISCALL_WRAPPER(MSVCP_invalid_argument_copy_ctor, 8)
602 invalid_argument* __thiscall MSVCP_invalid_argument_copy_ctor(
603         invalid_argument *this, invalid_argument *rhs)
604 {
605     TRACE("%p %p\n", this, rhs);
606     MSVCP_logic_error_copy_ctor(this, rhs);
607     this->e.vtable = &MSVCP_invalid_argument_vtable;
608     return this;
609 }
610
611 DEFINE_THISCALL_WRAPPER(MSVCP_invalid_argument_vector_dtor, 8)
612 void* __thiscall MSVCP_invalid_argument_vector_dtor(
613         invalid_argument *this, unsigned int flags)
614 {
615     TRACE("%p %x\n", this, flags);
616     return MSVCP_logic_error_vector_dtor(this, flags);
617 }
618
619 DEFINE_RTTI_DATA(invalid_argument, 0, 2, &logic_error_rtti_base_descriptor, &exception_rtti_base_descriptor, NULL, ".?AVinvalid_argument@std@@");
620
621 static const cxx_type_info invalid_argument_cxx_type_info = {
622     0,
623     &invalid_argument_type_info,
624     { 0, -1, 0 },
625     sizeof(invalid_argument),
626     (cxx_copy_ctor)THISCALL(MSVCP_invalid_argument_copy_ctor)
627 };
628
629 static const cxx_type_info_table invalid_argument_cxx_type_table = {
630     3,
631     {
632         &invalid_argument_cxx_type_info,
633         &logic_error_cxx_type_info,
634         &exception_cxx_type_info
635     }
636 };
637
638 static const cxx_exception_type invalid_argument_cxx_type = {
639     0,
640     (cxx_copy_ctor)THISCALL(MSVCP_logic_error_dtor),
641     NULL,
642     &invalid_argument_cxx_type_table
643 };
644
645 /* runtime_error class data */
646 typedef logic_error runtime_error;
647
648 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_ctor, 8)
649 runtime_error* __thiscall MSVCP_runtime_error_ctor(
650         runtime_error *this, const char *name)
651 {
652     TRACE("%p %s\n", this, name);
653     MSVCP_logic_error_ctor(this, name);
654     this->e.vtable = &MSVCP_runtime_error_vtable;
655     return this;
656 }
657
658 /* ??0runtime_error@std@@QAE@ABV01@@Z */
659 /* ??0runtime_error@std@@QEAA@AEBV01@@Z */
660 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_copy_ctor, 8)
661 runtime_error* __thiscall MSVCP_runtime_error_copy_ctor(
662         runtime_error *this, const runtime_error *rhs)
663 {
664     TRACE("%p %p\n", this, rhs);
665     MSVCP_logic_error_copy_ctor(this, rhs);
666     this->e.vtable = &MSVCP_runtime_error_vtable;
667     return this;
668 }
669
670 /* ??0runtime_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
671 /* ??0runtime_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
672 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_ctor_bstr, 8)
673 runtime_error* __thiscall MSVCP_runtime_error_ctor_bstr(runtime_error *this, const basic_string_char *str)
674 {
675     TRACE("(%p %p)\n", this, str);
676     return MSVCP_runtime_error_ctor(this, MSVCP_basic_string_char_c_str(str));
677 }
678
679 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_vector_dtor, 8)
680 void* __thiscall MSVCP_runtime_error_vector_dtor(
681         runtime_error *this, unsigned int flags)
682 {
683     TRACE("%p %x\n", this, flags);
684     return MSVCP_logic_error_vector_dtor(this, flags);
685 }
686
687 /* ??4runtime_error@std@@QAEAAV01@ABV01@@Z */
688 /* ??4runtime_error@std@@QEAAAEAV01@AEBV01@@Z */
689 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_assign, 8)
690 runtime_error* __thiscall MSVCP_runtime_error_assign(runtime_error *this, const runtime_error *assign)
691 {
692     MSVCP_logic_error_dtor(this);
693     return MSVCP_runtime_error_copy_ctor(this, assign);
694 }
695
696 DEFINE_RTTI_DATA(runtime_error, 0, 1, &exception_rtti_base_descriptor, NULL, NULL, ".?AVruntime_error@std@@");
697
698 static const cxx_type_info runtime_error_cxx_type_info = {
699     0,
700     &runtime_error_type_info,
701     { 0, -1, 0 },
702     sizeof(runtime_error),
703     (cxx_copy_ctor)THISCALL(MSVCP_runtime_error_copy_ctor)
704 };
705
706 static const cxx_type_info_table runtime_error_cxx_type_table = {
707     2,
708     {
709         &runtime_error_cxx_type_info,
710         &exception_cxx_type_info,
711         NULL
712     }
713 };
714
715 static const cxx_exception_type runtime_error_cxx_type = {
716     0,
717     (cxx_copy_ctor)THISCALL(MSVCP_logic_error_dtor),
718     NULL,
719     &runtime_error_cxx_type_table
720 };
721
722 /* ?what@runtime_error@std@@UBEPBDXZ */
723 /* ?what@runtime_error@std@@UEBAPEBDXZ */
724 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_what, 4)
725 const char* __thiscall MSVCP_runtime_error_what(runtime_error *this)
726 {
727     TRACE("%p\n", this);
728     return MSVCP_basic_string_char_c_str(&this->str);
729 }
730
731 #ifndef __GNUC__
732 void __asm_dummy_vtables(void) {
733 #endif
734     __ASM_VTABLE(type_info,"");
735     __ASM_VTABLE(exception,
736             VTABLE_ADD_FUNC(MSVCP_exception_what)
737             VTABLE_ADD_FUNC(MSVCP_exception__Doraise));
738     __ASM_VTABLE(bad_alloc,
739             VTABLE_ADD_FUNC(MSVCP_exception_what)
740             VTABLE_ADD_FUNC(MSVCP_exception__Doraise));
741     __ASM_VTABLE(logic_error,
742             VTABLE_ADD_FUNC(MSVCP_logic_error_what)
743             VTABLE_ADD_FUNC(MSVCP_exception__Doraise));
744     __ASM_VTABLE(length_error,
745             VTABLE_ADD_FUNC(MSVCP_logic_error_what)
746             VTABLE_ADD_FUNC(MSVCP_exception__Doraise));
747     __ASM_VTABLE(out_of_range,
748             VTABLE_ADD_FUNC(MSVCP_logic_error_what)
749             VTABLE_ADD_FUNC(MSVCP_exception__Doraise));
750     __ASM_VTABLE(invalid_argument,
751             VTABLE_ADD_FUNC(MSVCP_logic_error_what)
752             VTABLE_ADD_FUNC(MSVCP_exception__Doraise));
753     __ASM_VTABLE(runtime_error,
754             VTABLE_ADD_FUNC(MSVCP_runtime_error_what)
755             VTABLE_ADD_FUNC(MSVCP_exception__Doraise));
756 #ifndef __GNUC__
757 }
758 #endif
759
760 /* Internal: throws selected exception */
761 void throw_exception(exception_type et, const char *str)
762 {
763     switch(et) {
764     case EXCEPTION: {
765         exception e;
766         MSVCP_exception_ctor(&e, str);
767         _CxxThrowException(&e, &exception_cxx_type);
768     }
769     case EXCEPTION_BAD_ALLOC: {
770         bad_alloc e;
771         MSVCP_bad_alloc_ctor(&e, str);
772         _CxxThrowException(&e, &bad_alloc_cxx_type);
773     }
774     case EXCEPTION_LOGIC_ERROR: {
775         logic_error e;
776         MSVCP_logic_error_ctor(&e, str);
777         _CxxThrowException((exception*)&e, &logic_error_cxx_type);
778     }
779     case EXCEPTION_LENGTH_ERROR: {
780         length_error e;
781         MSVCP_length_error_ctor(&e, str);
782         _CxxThrowException((exception*)&e, &length_error_cxx_type);
783     }
784     case EXCEPTION_OUT_OF_RANGE: {
785         out_of_range e;
786         MSVCP_out_of_range_ctor(&e, str);
787         _CxxThrowException((exception*)&e, &out_of_range_cxx_type);
788     }
789     case EXCEPTION_INVALID_ARGUMENT: {
790         invalid_argument e;
791         MSVCP_invalid_argument_ctor(&e, str);
792         _CxxThrowException((exception*)&e, &invalid_argument_cxx_type);
793     }
794     case EXCEPTION_RUNTIME_ERROR: {
795         runtime_error e;
796         MSVCP_runtime_error_ctor(&e, str);
797         _CxxThrowException((exception*)&e, &runtime_error_cxx_type);
798     }
799     }
800 }