winebuild: Use strarray objects instead of pointers where possible.
[wine.git] / dlls / msvcp90 / exception.c
blobd323ded1d089d7aa28d480d2b63056ac23d8c0ce
1 /*
2 * Copyright 2010 Piotr Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "config.h"
21 #include <stdarg.h>
23 #include "msvcp90.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wine/debug.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(msvcp);
29 #define CLASS_IS_SIMPLE_TYPE 1
30 #define CLASS_HAS_VIRTUAL_BASE_CLASS 4
32 void WINAPI _CxxThrowException(exception*,const cxx_exception_type*);
34 #if _MSVCP_VER >= 70 || defined(_MSVCIRT)
35 typedef const char **exception_name;
36 #define EXCEPTION_STR(name) (*name)
37 #define EXCEPTION_NAME(str) ((exception_name)&str)
38 #else
39 typedef const char *exception_name;
40 #define EXCEPTION_STR(name) (name)
41 #define EXCEPTION_NAME(str) (str)
42 #endif
44 /* vtables */
45 extern const vtable_ptr MSVCP_exception_vtable;
46 /* ??_7bad_alloc@std@@6B@ */
47 extern const vtable_ptr MSVCP_bad_alloc_vtable;
48 /* ??_7logic_error@std@@6B@ */
49 extern const vtable_ptr MSVCP_logic_error_vtable;
50 /* ??_7length_error@std@@6B@ */
51 extern const vtable_ptr MSVCP_length_error_vtable;
52 /* ??_7out_of_range@std@@6B@ */
53 extern const vtable_ptr MSVCP_out_of_range_vtable;
54 extern const vtable_ptr MSVCP_invalid_argument_vtable;
55 /* ??_7runtime_error@std@@6B@ */
56 extern const vtable_ptr MSVCP_runtime_error_vtable;
57 extern const vtable_ptr MSVCP_failure_vtable;
58 /* ??_7bad_cast@std@@6B@ */
59 extern const vtable_ptr MSVCP_bad_cast_vtable;
61 static void MSVCP_type_info_dtor(type_info * _this)
63 free(_this->name);
66 /* Unexported */
67 DEFINE_THISCALL_WRAPPER(MSVCP_type_info_vector_dtor,8)
68 void * __thiscall MSVCP_type_info_vector_dtor(type_info * _this, unsigned int flags)
70 TRACE("(%p %x)\n", _this, flags);
71 if (flags & 2)
73 /* we have an array, with the number of elements stored before the first object */
74 INT_PTR i, *ptr = (INT_PTR *)_this - 1;
76 for (i = *ptr - 1; i >= 0; i--) MSVCP_type_info_dtor(_this + i);
77 MSVCRT_operator_delete(ptr);
79 else
81 MSVCP_type_info_dtor(_this);
82 if (flags & 1) MSVCRT_operator_delete(_this);
84 return _this;
87 DEFINE_RTTI_DATA0( type_info, 0, ".?AVtype_info@@" )
89 /* ??0exception@@QAE@ABQBD@Z */
90 /* ??0exception@@QEAA@AEBQEBD@Z */
91 DEFINE_THISCALL_WRAPPER(MSVCP_exception_ctor,8)
92 exception* __thiscall MSVCP_exception_ctor(exception *this, exception_name name)
94 TRACE("(%p %s)\n", this, EXCEPTION_STR(name));
96 this->vtable = &MSVCP_exception_vtable;
97 if(EXCEPTION_STR(name)) {
98 unsigned int name_len = strlen(EXCEPTION_STR(name)) + 1;
99 this->name = malloc(name_len);
100 memcpy(this->name, EXCEPTION_STR(name), name_len);
101 this->do_free = TRUE;
102 } else {
103 this->name = NULL;
104 this->do_free = FALSE;
106 return this;
109 DEFINE_THISCALL_WRAPPER(MSVCP_exception_copy_ctor,8)
110 exception* __thiscall MSVCP_exception_copy_ctor(exception *this, const exception *rhs)
112 TRACE("(%p,%p)\n", this, rhs);
114 if(!rhs->do_free) {
115 this->vtable = &MSVCP_exception_vtable;
116 this->name = rhs->name;
117 this->do_free = FALSE;
118 } else
119 MSVCP_exception_ctor(this, EXCEPTION_NAME(rhs->name));
120 TRACE("name = %s\n", this->name);
121 return this;
124 /* ??0exception@@QAE@XZ */
125 /* ??0exception@@QEAA@XZ */
126 DEFINE_THISCALL_WRAPPER(MSVCP_exception_default_ctor,4)
127 exception* __thiscall MSVCP_exception_default_ctor(exception *this)
129 TRACE("(%p)\n", this);
130 this->vtable = &MSVCP_exception_vtable;
131 this->name = NULL;
132 this->do_free = FALSE;
133 return this;
136 DEFINE_THISCALL_WRAPPER(MSVCP_exception_dtor,4)
137 void __thiscall MSVCP_exception_dtor(exception *this)
139 TRACE("(%p)\n", this);
140 this->vtable = &MSVCP_exception_vtable;
141 if(this->do_free)
142 free(this->name);
145 DEFINE_THISCALL_WRAPPER(MSVCP_exception_vector_dtor, 8)
146 void * __thiscall MSVCP_exception_vector_dtor(exception *this, unsigned int flags)
148 TRACE("%p %x\n", this, flags);
149 if(flags & 2) {
150 /* we have an array, with the number of elements stored before the first object */
151 INT_PTR i, *ptr = (INT_PTR *)this-1;
153 for(i=*ptr-1; i>=0; i--)
154 MSVCP_exception_dtor(this+i);
155 MSVCRT_operator_delete(ptr);
156 } else {
157 MSVCP_exception_dtor(this);
158 if(flags & 1)
159 MSVCRT_operator_delete(this);
162 return this;
165 /* ??_Gexception@@UAEPAXI@Z */
166 DEFINE_THISCALL_WRAPPER(MSVCP_exception_scalar_dtor, 8)
167 void * __thiscall MSVCP_exception_scalar_dtor(exception *this, unsigned int flags)
169 TRACE("(%p %x)\n", this, flags);
170 MSVCP_exception_dtor(this);
171 if (flags & 1) MSVCRT_operator_delete(this);
172 return this;
175 /* ??4exception@@QAEAAV0@ABV0@@Z */
176 /* ??4exception@@QEAAAEAV0@AEBV0@@Z */
177 DEFINE_THISCALL_WRAPPER(MSVCP_exception_assign, 8)
178 exception* __thiscall MSVCP_exception_assign(exception *this, const exception *assign)
180 MSVCP_exception_dtor(this);
181 return MSVCP_exception_copy_ctor(this, assign);
184 /* ?_Doraise@bad_alloc@std@@MBEXXZ */
185 /* ?_Doraise@bad_alloc@std@@MEBAXXZ */
186 /* ?_Doraise@logic_error@std@@MBEXXZ */
187 /* ?_Doraise@logic_error@std@@MEBAXXZ */
188 /* ?_Doraise@length_error@std@@MBEXXZ */
189 /* ?_Doraise@length_error@std@@MEBAXXZ */
190 /* ?_Doraise@out_of_range@std@@MBEXXZ */
191 /* ?_Doraise@out_of_range@std@@MEBAXXZ */
192 /* ?_Doraise@runtime_error@std@@MBEXXZ */
193 /* ?_Doraise@runtime_error@std@@MEBAXXZ */
194 /* ?_Doraise@bad_cast@std@@MBEXXZ */
195 /* ?_Doraise@bad_cast@std@@MEBAXXZ */
196 DEFINE_THISCALL_WRAPPER(MSVCP_exception__Doraise, 4)
197 void __thiscall MSVCP_exception__Doraise(exception *this)
199 FIXME("(%p) stub\n", this);
202 DEFINE_THISCALL_WRAPPER(MSVCP_exception_what,4)
203 const char* __thiscall MSVCP_exception_what(exception * this)
205 TRACE("(%p) returning %s\n", this, this->name);
206 return this->name ? this->name : "Unknown exception";
209 #ifdef _MSVCIRT
210 DEFINE_RTTI_DATA0(exception, 0, ".?AVexception@std@@")
211 #else
212 DEFINE_RTTI_DATA0(exception, 0, ".?AVexception@@")
213 #endif
214 DEFINE_CXX_DATA0(exception, MSVCP_exception_dtor)
216 /* bad_alloc class data */
217 typedef exception bad_alloc;
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, exception_name name)
224 TRACE("%p %s\n", this, EXCEPTION_STR(name));
225 MSVCP_exception_ctor(this, name);
226 this->vtable = &MSVCP_bad_alloc_vtable;
227 return this;
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)
235 static const char name[] = "bad allocation";
236 return MSVCP_bad_alloc_ctor(this, EXCEPTION_NAME(name));
239 /* ??0bad_alloc@std@@QAE@ABV01@@Z */
240 /* ??0bad_alloc@std@@QEAA@AEBV01@@Z */
241 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_copy_ctor, 8)
242 bad_alloc* __thiscall MSVCP_bad_alloc_copy_ctor(bad_alloc *this, const bad_alloc *rhs)
244 TRACE("%p %p\n", this, rhs);
245 MSVCP_exception_copy_ctor(this, rhs);
246 this->vtable = &MSVCP_bad_alloc_vtable;
247 return this;
250 /* ??1bad_alloc@std@@UAE@XZ */
251 /* ??1bad_alloc@std@@UEAA@XZ */
252 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_dtor, 4)
253 void __thiscall MSVCP_bad_alloc_dtor(bad_alloc *this)
255 TRACE("%p\n", this);
256 MSVCP_exception_dtor(this);
259 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_vector_dtor, 8)
260 void * __thiscall MSVCP_bad_alloc_vector_dtor(bad_alloc *this, unsigned int flags)
262 TRACE("%p %x\n", this, flags);
263 if(flags & 2) {
264 /* we have an array, with the number of elements stored before the first object */
265 INT_PTR i, *ptr = (INT_PTR *)this-1;
267 for(i=*ptr-1; i>=0; i--)
268 MSVCP_bad_alloc_dtor(this+i);
269 MSVCRT_operator_delete(ptr);
270 } else {
271 MSVCP_bad_alloc_dtor(this);
272 if(flags & 1)
273 MSVCRT_operator_delete(this);
276 return this;
279 /* ??4bad_alloc@std@@QAEAAV01@ABV01@@Z */
280 /* ??4bad_alloc@std@@QEAAAEAV01@AEBV01@@Z */
281 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_assign, 8)
282 bad_alloc* __thiscall MSVCP_bad_alloc_assign(bad_alloc *this, const bad_alloc *assign)
284 MSVCP_bad_alloc_dtor(this);
285 return MSVCP_bad_alloc_copy_ctor(this, assign);
288 DEFINE_RTTI_DATA1(bad_alloc, 0, &exception_rtti_base_descriptor, ".?AVbad_alloc@std@@")
289 DEFINE_CXX_DATA1(bad_alloc, &exception_cxx_type_info, MSVCP_bad_alloc_dtor)
291 /* logic_error class data */
292 typedef struct {
293 exception e;
294 #ifndef _MSVCIRT
295 basic_string_char str;
296 #endif
297 } logic_error;
299 /* ??0logic_error@@QAE@ABQBD@Z */
300 /* ??0logic_error@@QEAA@AEBQEBD@Z */
301 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_ctor, 8)
302 logic_error* __thiscall MSVCP_logic_error_ctor( logic_error *this, exception_name name )
304 TRACE("%p %s\n", this, EXCEPTION_STR(name));
305 #ifdef _MSVCIRT
306 MSVCP_exception_ctor(&this->e, name);
307 #else
308 this->e.name = NULL;
309 this->e.do_free = FALSE;
310 MSVCP_basic_string_char_ctor_cstr(&this->str, EXCEPTION_STR(name));
311 #endif
312 this->e.vtable = &MSVCP_logic_error_vtable;
313 return this;
316 /* ??0logic_error@std@@QAE@ABV01@@Z */
317 /* ??0logic_error@std@@QEAA@AEBV01@@Z */
318 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_copy_ctor, 8)
319 logic_error* __thiscall MSVCP_logic_error_copy_ctor(
320 logic_error *this, const logic_error *rhs)
322 TRACE("%p %p\n", this, rhs);
323 MSVCP_exception_copy_ctor(&this->e, &rhs->e);
324 #ifndef _MSVCIRT
325 MSVCP_basic_string_char_copy_ctor(&this->str, &rhs->str);
326 #endif
327 this->e.vtable = &MSVCP_logic_error_vtable;
328 return this;
331 /* ??0logic_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
332 /* ??0logic_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
333 #ifndef _MSVCIRT
334 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_ctor_bstr, 8)
335 logic_error* __thiscall MSVCP_logic_error_ctor_bstr(logic_error *this, const basic_string_char *str)
337 const char *name = MSVCP_basic_string_char_c_str(str);
338 TRACE("(%p %p %s)\n", this, str, name);
339 return MSVCP_logic_error_ctor(this, EXCEPTION_NAME(name));
341 #endif
343 /* ??1logic_error@std@@UAE@XZ */
344 /* ??1logic_error@std@@UEAA@XZ */
345 /* ??1length_error@std@@UAE@XZ */
346 /* ??1length_error@std@@UEAA@XZ */
347 /* ??1out_of_range@std@@UAE@XZ */
348 /* ??1out_of_range@std@@UEAA@XZ */
349 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_dtor, 4)
350 void __thiscall MSVCP_logic_error_dtor(logic_error *this)
352 TRACE("%p\n", this);
353 MSVCP_exception_dtor(&this->e);
354 #ifndef _MSVCIRT
355 MSVCP_basic_string_char_dtor(&this->str);
356 #endif
359 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_vector_dtor, 8)
360 void* __thiscall MSVCP_logic_error_vector_dtor(
361 logic_error *this, unsigned int flags)
363 TRACE("%p %x\n", this, flags);
364 if(flags & 2) {
365 /* we have an array, with the number of elements stored before the first object */
366 INT_PTR i, *ptr = (INT_PTR *)this-1;
368 for(i=*ptr-1; i>=0; i--)
369 MSVCP_logic_error_dtor(this+i);
370 MSVCRT_operator_delete(ptr);
371 } else {
372 MSVCP_logic_error_dtor(this);
373 if(flags & 1)
374 MSVCRT_operator_delete(this);
377 return this;
380 /* ??_Glogic_error@@UAEPAXI@Z */
381 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_scalar_dtor, 8)
382 void * __thiscall MSVCP_logic_error_scalar_dtor(logic_error *this, unsigned int flags)
384 TRACE("(%p %x)\n", this, flags);
385 MSVCP_logic_error_dtor(this);
386 if (flags & 1) MSVCRT_operator_delete(this);
387 return this;
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)
395 MSVCP_logic_error_dtor(this);
396 return MSVCP_logic_error_copy_ctor(this, assign);
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)
404 TRACE("%p\n", this);
405 #ifdef _MSVCIRT
406 return MSVCP_exception_what( &this->e );
407 #else
408 return MSVCP_basic_string_char_c_str(&this->str);
409 #endif
412 #ifdef _MSVCIRT
413 DEFINE_RTTI_DATA1(logic_error, 0, &exception_rtti_base_descriptor, ".?AVlogic_error@std@@")
414 #else
415 DEFINE_RTTI_DATA1(logic_error, 0, &exception_rtti_base_descriptor, ".?AVlogic_error@@")
416 #endif
417 DEFINE_CXX_DATA1(logic_error, &exception_cxx_type_info, MSVCP_logic_error_dtor)
419 /* length_error class data */
420 typedef logic_error length_error;
422 static length_error* MSVCP_length_error_ctor( length_error *this, exception_name name )
424 TRACE("%p %s\n", this, EXCEPTION_STR(name));
425 MSVCP_logic_error_ctor(this, name);
426 this->e.vtable = &MSVCP_length_error_vtable;
427 return this;
430 /* ??0length_error@std@@QAE@ABV01@@Z */
431 /* ??0length_error@std@@QEAA@AEBV01@@Z */
432 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_copy_ctor, 8)
433 length_error* __thiscall MSVCP_length_error_copy_ctor(
434 length_error *this, const length_error *rhs)
436 TRACE("%p %p\n", this, rhs);
437 MSVCP_logic_error_copy_ctor(this, rhs);
438 this->e.vtable = &MSVCP_length_error_vtable;
439 return this;
442 /* ??0length_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
443 /* ??0length_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
444 #ifndef _MSVCIRT
445 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_ctor_bstr, 8)
446 length_error* __thiscall MSVCP_length_error_ctor_bstr(length_error *this, const basic_string_char *str)
448 const char *name = MSVCP_basic_string_char_c_str(str);
449 TRACE("(%p %p %s)\n", this, str, name);
450 return MSVCP_length_error_ctor(this, EXCEPTION_NAME(name));
452 #endif
454 /* ??4length_error@std@@QAEAAV01@ABV01@@Z */
455 /* ??4length_error@std@@QEAAAEAV01@AEBV01@@Z */
456 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_assign, 8)
457 length_error* __thiscall MSVCP_length_error_assign(length_error *this, const length_error *assign)
459 MSVCP_logic_error_dtor(this);
460 return MSVCP_length_error_copy_ctor(this, assign);
463 DEFINE_RTTI_DATA2(length_error, 0, &logic_error_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AVlength_error@std@@")
464 DEFINE_CXX_DATA2(length_error, &logic_error_cxx_type_info, &exception_cxx_type_info, MSVCP_logic_error_dtor)
466 /* out_of_range class data */
467 typedef logic_error out_of_range;
469 static out_of_range* MSVCP_out_of_range_ctor( out_of_range *this, exception_name name )
471 TRACE("%p %s\n", this, EXCEPTION_STR(name));
472 MSVCP_logic_error_ctor(this, name);
473 this->e.vtable = &MSVCP_out_of_range_vtable;
474 return this;
477 /* ??0out_of_range@std@@QAE@ABV01@@Z */
478 /* ??0out_of_range@std@@QEAA@AEBV01@@Z */
479 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_copy_ctor, 8)
480 out_of_range* __thiscall MSVCP_out_of_range_copy_ctor(
481 out_of_range *this, const out_of_range *rhs)
483 TRACE("%p %p\n", this, rhs);
484 MSVCP_logic_error_copy_ctor(this, rhs);
485 this->e.vtable = &MSVCP_out_of_range_vtable;
486 return this;
489 /* ??0out_of_range@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
490 /* ??0out_of_range@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
491 #ifndef _MSVCIRT
492 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_ctor_bstr, 8)
493 out_of_range* __thiscall MSVCP_out_of_range_ctor_bstr(out_of_range *this, const basic_string_char *str)
495 const char *name = MSVCP_basic_string_char_c_str(str);
496 TRACE("(%p %p %s)\n", this, str, name);
497 return MSVCP_out_of_range_ctor(this, EXCEPTION_NAME(name));
499 #endif
501 /* ??4out_of_range@std@@QAEAAV01@ABV01@@Z */
502 /* ??4out_of_range@std@@QEAAAEAV01@AEBV01@@Z */
503 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_assign, 8)
504 out_of_range* __thiscall MSVCP_out_of_range_assign(out_of_range *this, const out_of_range *assign)
506 MSVCP_logic_error_dtor(this);
507 return MSVCP_out_of_range_copy_ctor(this, assign);
510 DEFINE_RTTI_DATA2(out_of_range, 0, &logic_error_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AVout_of_range@std@@")
511 DEFINE_CXX_DATA2(out_of_range, &logic_error_cxx_type_info, &exception_cxx_type_info, MSVCP_logic_error_dtor)
513 /* invalid_argument class data */
514 typedef logic_error invalid_argument;
516 static invalid_argument* MSVCP_invalid_argument_ctor( invalid_argument *this, exception_name name )
518 TRACE("%p %s\n", this, EXCEPTION_STR(name));
519 MSVCP_logic_error_ctor(this, name);
520 this->e.vtable = &MSVCP_invalid_argument_vtable;
521 return this;
524 DEFINE_THISCALL_WRAPPER(MSVCP_invalid_argument_copy_ctor, 8)
525 invalid_argument* __thiscall MSVCP_invalid_argument_copy_ctor(
526 invalid_argument *this, invalid_argument *rhs)
528 TRACE("%p %p\n", this, rhs);
529 MSVCP_logic_error_copy_ctor(this, rhs);
530 this->e.vtable = &MSVCP_invalid_argument_vtable;
531 return this;
534 DEFINE_RTTI_DATA2(invalid_argument, 0, &logic_error_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AVinvalid_argument@std@@")
535 DEFINE_CXX_DATA2(invalid_argument, &logic_error_cxx_type_info, &exception_cxx_type_info, MSVCP_logic_error_dtor)
537 /* runtime_error class data */
538 typedef struct {
539 exception e;
540 basic_string_char str;
541 } runtime_error;
543 static runtime_error* MSVCP_runtime_error_ctor( runtime_error *this, exception_name name )
545 TRACE("%p %s\n", this, EXCEPTION_STR(name));
546 #ifdef _MSVCIRT
547 MSVCP_exception_ctor(&this->e, name);
548 #else
549 this->e.name = NULL;
550 this->e.do_free = FALSE;
551 MSVCP_basic_string_char_ctor_cstr(&this->str, EXCEPTION_STR(name));
552 #endif
553 this->e.vtable = &MSVCP_runtime_error_vtable;
554 return this;
557 /* ??0runtime_error@std@@QAE@ABV01@@Z */
558 /* ??0runtime_error@std@@QEAA@AEBV01@@Z */
559 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_copy_ctor, 8)
560 runtime_error* __thiscall MSVCP_runtime_error_copy_ctor(
561 runtime_error *this, const runtime_error *rhs)
563 TRACE("%p %p\n", this, rhs);
564 MSVCP_exception_copy_ctor(&this->e, &rhs->e);
565 #ifndef _MSVCIRT
566 MSVCP_basic_string_char_copy_ctor(&this->str, &rhs->str);
567 #endif
568 this->e.vtable = &MSVCP_runtime_error_vtable;
569 return this;
572 /* ??0runtime_error@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
573 /* ??0runtime_error@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@@Z */
574 #ifndef _MSVCIRT
575 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_ctor_bstr, 8)
576 runtime_error* __thiscall MSVCP_runtime_error_ctor_bstr(runtime_error *this, const basic_string_char *str)
578 const char *name = MSVCP_basic_string_char_c_str(str);
579 TRACE("(%p %p %s)\n", this, str, name);
580 return MSVCP_runtime_error_ctor(this, EXCEPTION_NAME(name));
582 #endif
584 /* ??1runtime_error@std@@UAE@XZ */
585 /* ??1runtime_error@std@@UEAA@XZ */
586 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_dtor, 4)
587 void __thiscall MSVCP_runtime_error_dtor(runtime_error *this)
589 TRACE("%p\n", this);
590 MSVCP_exception_dtor(&this->e);
591 #ifndef _MSVCIRT
592 MSVCP_basic_string_char_dtor(&this->str);
593 #endif
596 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_vector_dtor, 8)
597 void* __thiscall MSVCP_runtime_error_vector_dtor(
598 runtime_error *this, unsigned int flags)
600 TRACE("%p %x\n", this, flags);
601 if(flags & 2) {
602 /* we have an array, with the number of elements stored before the first object */
603 INT_PTR i, *ptr = (INT_PTR *)this-1;
605 for(i=*ptr-1; i>=0; i--)
606 MSVCP_runtime_error_dtor(this+i);
607 MSVCRT_operator_delete(ptr);
608 } else {
609 MSVCP_runtime_error_dtor(this);
610 if(flags & 1)
611 MSVCRT_operator_delete(this);
614 return this;
617 /* ??4runtime_error@std@@QAEAAV01@ABV01@@Z */
618 /* ??4runtime_error@std@@QEAAAEAV01@AEBV01@@Z */
619 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_assign, 8)
620 runtime_error* __thiscall MSVCP_runtime_error_assign(runtime_error *this, const runtime_error *assign)
622 MSVCP_runtime_error_dtor(this);
623 return MSVCP_runtime_error_copy_ctor(this, assign);
626 /* ?what@runtime_error@std@@UBEPBDXZ */
627 /* ?what@runtime_error@std@@UEBAPEBDXZ */
628 DEFINE_THISCALL_WRAPPER(MSVCP_runtime_error_what, 4)
629 const char* __thiscall MSVCP_runtime_error_what(runtime_error *this)
631 TRACE("%p\n", this);
632 #ifdef _MSVCIRT
633 return MSVCP_exception_what( &this->e );
634 #else
635 return MSVCP_basic_string_char_c_str(&this->str);
636 #endif
639 DEFINE_RTTI_DATA1(runtime_error, 0, &exception_rtti_base_descriptor, ".?AVruntime_error@std@@")
640 DEFINE_CXX_DATA1(runtime_error, &exception_cxx_type_info, MSVCP_runtime_error_dtor)
642 /* failure class data */
643 typedef runtime_error failure;
645 static failure* MSVCP_failure_ctor( failure *this, exception_name name )
647 TRACE("%p %s\n", this, EXCEPTION_STR(name));
648 MSVCP_runtime_error_ctor(this, name);
649 this->e.vtable = &MSVCP_failure_vtable;
650 return this;
653 DEFINE_THISCALL_WRAPPER(MSVCP_failure_copy_ctor, 8)
654 failure* __thiscall MSVCP_failure_copy_ctor(
655 failure *this, failure *rhs)
657 TRACE("%p %p\n", this, rhs);
658 MSVCP_runtime_error_copy_ctor(this, rhs);
659 this->e.vtable = &MSVCP_failure_vtable;
660 return this;
663 DEFINE_THISCALL_WRAPPER(MSVCP_failure_dtor, 4)
664 void __thiscall MSVCP_failure_dtor(failure *this)
666 TRACE("%p\n", this);
667 MSVCP_runtime_error_dtor(this);
670 DEFINE_THISCALL_WRAPPER(MSVCP_failure_vector_dtor, 8)
671 void* __thiscall MSVCP_failure_vector_dtor(
672 failure *this, unsigned int flags)
674 TRACE("%p %x\n", this, flags);
675 return MSVCP_runtime_error_vector_dtor(this, flags);
678 DEFINE_THISCALL_WRAPPER(MSVCP_failure_what, 4)
679 const char* __thiscall MSVCP_failure_what(failure *this)
681 TRACE("%p\n", this);
682 return MSVCP_runtime_error_what(this);
685 DEFINE_RTTI_DATA2(failure, 0, &runtime_error_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AVfailure@std@@")
686 DEFINE_CXX_DATA2(failure, &runtime_error_cxx_type_info, &exception_cxx_type_info, MSVCP_runtime_error_dtor)
688 /* bad_cast class data */
689 typedef exception bad_cast;
691 /* ??0bad_cast@std@@QAE@PBD@Z */
692 /* ??0bad_cast@std@@QEAA@PEBD@Z */
693 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_ctor, 8)
694 bad_cast* __thiscall MSVCP_bad_cast_ctor(bad_cast *this, const char *name)
696 TRACE("%p %s\n", this, name);
697 MSVCP_exception_ctor(this, EXCEPTION_NAME(name));
698 this->vtable = &MSVCP_bad_cast_vtable;
699 return this;
702 /* ??_Fbad_cast@@QAEXXZ */
703 /* ??_Fbad_cast@std@@QEAAXXZ */
704 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_default_ctor,4)
705 bad_cast* __thiscall MSVCP_bad_cast_default_ctor(bad_cast *this)
707 return MSVCP_bad_cast_ctor(this, "bad cast");
710 /* ??0bad_cast@std@@QAE@ABV01@@Z */
711 /* ??0bad_cast@std@@QEAA@AEBV01@@Z */
712 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_copy_ctor, 8)
713 bad_cast* __thiscall MSVCP_bad_cast_copy_ctor(bad_cast *this, const bad_cast *rhs)
715 TRACE("%p %p\n", this, rhs);
716 MSVCP_exception_copy_ctor(this, rhs);
717 this->vtable = &MSVCP_bad_cast_vtable;
718 return this;
721 /* ??1bad_cast@@UAE@XZ */
722 /* ??1bad_cast@std@@UEAA@XZ */
723 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_dtor, 4)
724 void __thiscall MSVCP_bad_cast_dtor(bad_cast *this)
726 TRACE("%p\n", this);
727 MSVCP_exception_dtor(this);
730 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_vector_dtor, 8)
731 void * __thiscall MSVCP_bad_cast_vector_dtor(bad_cast *this, unsigned int flags)
733 TRACE("%p %x\n", this, flags);
734 if(flags & 2) {
735 /* we have an array, with the number of elements stored before the first object */
736 INT_PTR i, *ptr = (INT_PTR *)this-1;
738 for(i=*ptr-1; i>=0; i--)
739 MSVCP_bad_cast_dtor(this+i);
740 MSVCRT_operator_delete(ptr);
741 } else {
742 MSVCP_bad_cast_dtor(this);
743 if(flags & 1)
744 MSVCRT_operator_delete(this);
747 return this;
750 /* ??4bad_cast@std@@QAEAAV01@ABV01@@Z */
751 /* ??4bad_cast@std@@QEAAAEAV01@AEBV01@@Z */
752 DEFINE_THISCALL_WRAPPER(MSVCP_bad_cast_opequals, 8)
753 bad_cast* __thiscall MSVCP_bad_cast_opequals(bad_cast *this, const bad_cast *rhs)
755 TRACE("(%p %p)\n", this, rhs);
757 if(this != rhs) {
758 MSVCP_exception_dtor(this);
759 MSVCP_exception_copy_ctor(this, rhs);
761 return this;
764 DEFINE_RTTI_DATA1(bad_cast, 0, &exception_rtti_base_descriptor, ".?AVbad_cast@std@@")
765 DEFINE_CXX_DATA1(bad_cast, &exception_cxx_type_info, MSVCP_bad_cast_dtor)
767 /* ?_Nomemory@std@@YAXXZ */
768 void __cdecl _Nomemory(void)
770 TRACE("()\n");
771 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
774 /* ?_Xmem@tr1@std@@YAXXZ */
775 void __cdecl _Xmem(void)
777 TRACE("()\n");
778 throw_exception(EXCEPTION_BAD_ALLOC, NULL);
781 /* ?_Xinvalid_argument@std@@YAXPBD@Z */
782 /* ?_Xinvalid_argument@std@@YAXPEBD@Z */
783 void __cdecl _Xinvalid_argument(const char *str)
785 TRACE("(%s)\n", debugstr_a(str));
786 throw_exception(EXCEPTION_INVALID_ARGUMENT, str);
789 /* ?_Xlength_error@std@@YAXPBD@Z */
790 /* ?_Xlength_error@std@@YAXPEBD@Z */
791 void __cdecl _Xlength_error(const char *str)
793 TRACE("(%s)\n", debugstr_a(str));
794 throw_exception(EXCEPTION_LENGTH_ERROR, str);
797 /* ?_Xout_of_range@std@@YAXPBD@Z */
798 /* ?_Xout_of_range@std@@YAXPEBD@Z */
799 void __cdecl _Xout_of_range(const char *str)
801 TRACE("(%s)\n", debugstr_a(str));
802 throw_exception(EXCEPTION_OUT_OF_RANGE, str);
805 /* ?_Xruntime_error@std@@YAXPBD@Z */
806 /* ?_Xruntime_error@std@@YAXPEBD@Z */
807 void __cdecl _Xruntime_error(const char *str)
809 TRACE("(%s)\n", debugstr_a(str));
810 throw_exception(EXCEPTION_RUNTIME_ERROR, str);
813 /* ?uncaught_exception@std@@YA_NXZ */
814 MSVCP_bool __cdecl MSVCP__uncaught_exception(void)
816 return __uncaught_exception();
819 #if _MSVCP_VER >= 70 || defined(_MSVCIRT)
820 #define EXCEPTION_VTABLE(name,funcs) __ASM_VTABLE(name,funcs)
821 #else
822 #define EXCEPTION_VTABLE(name,funcs) __ASM_VTABLE(name,funcs VTABLE_ADD_FUNC(MSVCP_exception__Doraise))
823 #endif
825 #ifndef __GNUC__
826 void __asm_dummy_vtables(void) {
827 #endif
828 __ASM_VTABLE(type_info,
829 VTABLE_ADD_FUNC(MSVCP_type_info_vector_dtor));
830 EXCEPTION_VTABLE(exception,
831 VTABLE_ADD_FUNC(MSVCP_exception_vector_dtor)
832 VTABLE_ADD_FUNC(MSVCP_exception_what));
833 EXCEPTION_VTABLE(bad_alloc,
834 VTABLE_ADD_FUNC(MSVCP_bad_alloc_vector_dtor)
835 VTABLE_ADD_FUNC(MSVCP_exception_what));
836 EXCEPTION_VTABLE(logic_error,
837 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor)
838 VTABLE_ADD_FUNC(MSVCP_logic_error_what));
839 EXCEPTION_VTABLE(length_error,
840 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor)
841 VTABLE_ADD_FUNC(MSVCP_logic_error_what));
842 EXCEPTION_VTABLE(out_of_range,
843 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor)
844 VTABLE_ADD_FUNC(MSVCP_logic_error_what));
845 EXCEPTION_VTABLE(invalid_argument,
846 VTABLE_ADD_FUNC(MSVCP_logic_error_vector_dtor)
847 VTABLE_ADD_FUNC(MSVCP_logic_error_what));
848 EXCEPTION_VTABLE(runtime_error,
849 VTABLE_ADD_FUNC(MSVCP_runtime_error_vector_dtor)
850 VTABLE_ADD_FUNC(MSVCP_runtime_error_what));
851 EXCEPTION_VTABLE(failure,
852 VTABLE_ADD_FUNC(MSVCP_failure_vector_dtor)
853 VTABLE_ADD_FUNC(MSVCP_failure_what));
854 EXCEPTION_VTABLE(bad_cast,
855 VTABLE_ADD_FUNC(MSVCP_bad_cast_vector_dtor)
856 VTABLE_ADD_FUNC(MSVCP_exception_what));
857 #ifndef __GNUC__
859 #endif
861 /* Internal: throws selected exception */
862 void throw_exception(exception_type et, const char *str)
864 exception_name name = EXCEPTION_NAME(str);
866 switch(et) {
867 case EXCEPTION_RERAISE:
868 _CxxThrowException(NULL, NULL);
869 case EXCEPTION: {
870 exception e;
871 MSVCP_exception_ctor(&e, name);
872 _CxxThrowException(&e, &exception_cxx_type);
874 case EXCEPTION_BAD_ALLOC: {
875 bad_alloc e;
876 MSVCP_bad_alloc_ctor(&e, name);
877 _CxxThrowException(&e, &bad_alloc_cxx_type);
879 case EXCEPTION_BAD_CAST: {
880 bad_cast e;
881 MSVCP_bad_cast_ctor(&e, str);
882 _CxxThrowException(&e, &bad_cast_cxx_type);
884 case EXCEPTION_LOGIC_ERROR: {
885 logic_error e;
886 MSVCP_logic_error_ctor(&e, name);
887 _CxxThrowException((exception*)&e, &logic_error_cxx_type);
889 case EXCEPTION_LENGTH_ERROR: {
890 length_error e;
891 MSVCP_length_error_ctor(&e, name);
892 _CxxThrowException((exception*)&e, &length_error_cxx_type);
894 case EXCEPTION_OUT_OF_RANGE: {
895 out_of_range e;
896 MSVCP_out_of_range_ctor(&e, name);
897 _CxxThrowException((exception*)&e, &out_of_range_cxx_type);
899 case EXCEPTION_INVALID_ARGUMENT: {
900 invalid_argument e;
901 MSVCP_invalid_argument_ctor(&e, name);
902 _CxxThrowException((exception*)&e, &invalid_argument_cxx_type);
904 case EXCEPTION_RUNTIME_ERROR: {
905 runtime_error e;
906 MSVCP_runtime_error_ctor(&e, name);
907 _CxxThrowException((exception*)&e, &runtime_error_cxx_type);
909 case EXCEPTION_FAILURE: {
910 failure e;
911 MSVCP_failure_ctor(&e, name);
912 _CxxThrowException((exception*)&e, &failure_cxx_type);
917 void init_exception(void *base)
919 #ifdef __x86_64__
920 init_type_info_rtti(base);
921 init_exception_rtti(base);
922 init_bad_alloc_rtti(base);
923 init_logic_error_rtti(base);
924 init_length_error_rtti(base);
925 init_out_of_range_rtti(base);
926 init_invalid_argument_rtti(base);
927 init_runtime_error_rtti(base);
928 init_failure_rtti(base);
929 init_bad_cast_rtti(base);
931 init_exception_cxx(base);
932 init_bad_alloc_cxx(base);
933 init_logic_error_cxx(base);
934 init_length_error_cxx(base);
935 init_out_of_range_cxx(base);
936 init_invalid_argument_cxx(base);
937 init_runtime_error_cxx(base);
938 init_failure_cxx(base);
939 init_bad_cast_cxx(base);
940 #endif