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