ReactOS 0.4.15-dev-5895-g2687c1b
cpp.c
Go to the documentation of this file.
1/*
2 * msvcrt.dll C++ objects
3 *
4 * Copyright 2000 Jon Griffiths
5 * Copyright 2003, 2004 Alexandre Julliard
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#include "config.h"
23#include "wine/port.h"
24
25#include <stdarg.h>
26
27#include "windef.h"
28#include "winternl.h"
29#include "wine/exception.h"
30#include "wine/debug.h"
31#include "msvcrt.h"
32#include "cppexcept.h"
33#include "mtdll.h"
34#include "cxx.h"
35
37
39{
40 void *memPtr;
42};
43
44typedef exception bad_cast;
45typedef exception bad_typeid;
46typedef exception __non_rtti_object;
47
53
54/* get the vtable pointer for a C++ object */
55static inline const vtable_ptr *get_vtable( void *obj )
56{
57 return *(const vtable_ptr **)obj;
58}
59
60static inline const rtti_object_locator *get_obj_locator( void *cppobj )
61{
62 const vtable_ptr *vtable = get_vtable( cppobj );
63 return (const rtti_object_locator *)vtable[-1];
64}
65
66#ifndef __x86_64__
68{
69 int i;
70 const rtti_object_hierarchy *h = ptr->type_hierarchy;
71
72 TRACE( "%p: sig=%08x base_offset=%08x flags=%08x type=%p %s hierarchy=%p\n",
73 ptr, ptr->signature, ptr->base_class_offset, ptr->flags,
74 ptr->type_descriptor, dbgstr_type_info(ptr->type_descriptor), ptr->type_hierarchy );
75 TRACE( " hierarchy: sig=%08x attr=%08x len=%d base classes=%p\n",
76 h->signature, h->attributes, h->array_len, h->base_classes );
77 for (i = 0; i < h->array_len; i++)
78 {
79 TRACE( " base class %p: num %d off %d,%d,%d attr %08x type %p %s\n",
80 h->base_classes->bases[i],
81 h->base_classes->bases[i]->num_base_classes,
82 h->base_classes->bases[i]->offsets.this_offset,
83 h->base_classes->bases[i]->offsets.vbase_descr,
84 h->base_classes->bases[i]->offsets.vbase_offset,
85 h->base_classes->bases[i]->attributes,
86 h->base_classes->bases[i]->type_descriptor,
87 dbgstr_type_info(h->base_classes->bases[i]->type_descriptor) );
88 }
89}
90
91#else
92
93static void dump_obj_locator( const rtti_object_locator *ptr )
94{
95 int i;
96 char *base = ptr->signature == 0 ? RtlPcToFileHeader((void*)ptr, (void**)&base) : (char*)ptr - ptr->object_locator;
97 const rtti_object_hierarchy *h = (const rtti_object_hierarchy*)(base + ptr->type_hierarchy);
98 const type_info *type_descriptor = (const type_info*)(base + ptr->type_descriptor);
99
100 TRACE( "%p: sig=%08x base_offset=%08x flags=%08x type=%p %s hierarchy=%p\n",
101 ptr, ptr->signature, ptr->base_class_offset, ptr->flags,
102 type_descriptor, dbgstr_type_info(type_descriptor), h );
103 TRACE( " hierarchy: sig=%08x attr=%08x len=%d base classes=%p\n",
104 h->signature, h->attributes, h->array_len, base + h->base_classes );
105 for (i = 0; i < h->array_len; i++)
106 {
108 ((const rtti_base_array*)(base + h->base_classes))->bases[i]);
109
110 TRACE( " base class %p: num %d off %d,%d,%d attr %08x type %p %s\n",
111 bases,
112 bases->num_base_classes,
113 bases->offsets.this_offset,
114 bases->offsets.vbase_descr,
115 bases->offsets.vbase_offset,
116 bases->attributes,
117 base + bases->type_descriptor,
118 dbgstr_type_info((const type_info*)(base + bases->type_descriptor)) );
119 }
120}
121#endif
122
123/* Internal common ctor for exception */
124static void EXCEPTION_ctor(exception *_this, const char** name)
125{
127 if (*name)
128 {
129 unsigned int name_len = strlen(*name) + 1;
130 _this->name = MSVCRT_malloc(name_len);
131 memcpy(_this->name, *name, name_len);
132 _this->do_free = TRUE;
133 }
134 else
135 {
136 _this->name = NULL;
137 _this->do_free = FALSE;
138 }
139}
140
141#ifdef __REACTOS__
142#include <internal/wine_msc.h>
143#endif /* __REACTOS__ */
144
145/******************************************************************
146 * ??0exception@@QAE@ABQBD@Z (MSVCRT.@)
147 */
150{
151 TRACE("(%p,%s)\n", _this, *name);
152 EXCEPTION_ctor(_this, name);
153 return _this;
154}
155
156/******************************************************************
157 * ??0exception@@QAE@ABQBDH@Z (MSVCRT.@)
158 */
161{
162 TRACE("(%p,%s)\n", _this, *name);
163 _this->vtable = &MSVCRT_exception_vtable;
164 _this->name = *name;
165 _this->do_free = FALSE;
166 return _this;
167}
168
169/******************************************************************
170 * ??0exception@@QAE@ABV0@@Z (MSVCRT.@)
171 */
174{
175 TRACE("(%p,%p)\n", _this, rhs);
176
177 if (!rhs->do_free)
178 {
179 _this->vtable = &MSVCRT_exception_vtable;
180 _this->name = rhs->name;
181 _this->do_free = FALSE;
182 }
183 else
184 EXCEPTION_ctor(_this, (const char**)&rhs->name);
185 TRACE("name = %s\n", _this->name);
186 return _this;
187}
188
189/******************************************************************
190 * ??0exception@@QAE@XZ (MSVCRT.@)
191 */
194{
195 static const char* empty = NULL;
196
197 TRACE("(%p)\n", _this);
198 EXCEPTION_ctor(_this, &empty);
199 return _this;
200}
201
202/******************************************************************
203 * ??1exception@@UAE@XZ (MSVCRT.@)
204 */
207{
208 TRACE("(%p)\n", _this);
209 _this->vtable = &MSVCRT_exception_vtable;
210 if (_this->do_free) MSVCRT_free(_this->name);
211}
212
213/******************************************************************
214 * ??4exception@@QAEAAV0@ABV0@@Z (MSVCRT.@)
215 */
218{
219 TRACE("(%p %p)\n", _this, rhs);
220 if (_this != rhs)
221 {
223 MSVCRT_exception_copy_ctor(_this, rhs);
224 }
225 TRACE("name = %s\n", _this->name);
226 return _this;
227}
228
229/******************************************************************
230 * ??_Eexception@@UAEPAXI@Z (MSVCRT.@)
231 */
234{
235 TRACE("(%p %x)\n", _this, flags);
236 if (flags & 2)
237 {
238 /* we have an array, with the number of elements stored before the first object */
239 INT_PTR i, *ptr = (INT_PTR *)_this - 1;
240
241 for (i = *ptr - 1; i >= 0; i--) MSVCRT_exception_dtor(_this + i);
243 }
244 else
245 {
247 if (flags & 1) MSVCRT_operator_delete(_this);
248 }
249 return _this;
250}
251
252/******************************************************************
253 * ??_Gexception@@UAEPAXI@Z (MSVCRT.@)
254 */
257{
258 TRACE("(%p %x)\n", _this, flags);
260 if (flags & 1) MSVCRT_operator_delete(_this);
261 return _this;
262}
263
264/******************************************************************
265 * ?what@exception@@UBEPBDXZ (MSVCRT.@)
266 */
269{
270 TRACE("(%p) returning %s\n", _this, _this->name);
271 return _this->name ? _this->name : "Unknown exception";
272}
273
274/******************************************************************
275 * ??0bad_typeid@@QAE@ABV0@@Z (MSVCRT.@)
276 */
278bad_typeid * __thiscall MSVCRT_bad_typeid_copy_ctor(bad_typeid * _this, const bad_typeid * rhs)
279{
280 TRACE("(%p %p)\n", _this, rhs);
281 MSVCRT_exception_copy_ctor(_this, rhs);
282 _this->vtable = &MSVCRT_bad_typeid_vtable;
283 return _this;
284}
285
286/******************************************************************
287 * ??0bad_typeid@@QAE@PBD@Z (MSVCRT.@)
288 */
290bad_typeid * __thiscall MSVCRT_bad_typeid_ctor(bad_typeid * _this, const char * name)
291{
292 TRACE("(%p %s)\n", _this, name);
293 EXCEPTION_ctor(_this, &name);
294 _this->vtable = &MSVCRT_bad_typeid_vtable;
295 return _this;
296}
297
298/******************************************************************
299 * ??_Fbad_typeid@@QAEXXZ (MSVCRT.@)
300 */
302bad_typeid * __thiscall MSVCRT_bad_typeid_default_ctor(bad_typeid * _this)
303{
304 return MSVCRT_bad_typeid_ctor( _this, "bad typeid" );
305}
306
307/******************************************************************
308 * ??1bad_typeid@@UAE@XZ (MSVCRT.@)
309 */
312{
313 TRACE("(%p)\n", _this);
315}
316
317/******************************************************************
318 * ??4bad_typeid@@QAEAAV0@ABV0@@Z (MSVCRT.@)
319 */
321bad_typeid * __thiscall MSVCRT_bad_typeid_opequals(bad_typeid * _this, const bad_typeid * rhs)
322{
323 TRACE("(%p %p)\n", _this, rhs);
324 MSVCRT_exception_opequals(_this, rhs);
325 return _this;
326}
327
328/******************************************************************
329 * ??_Ebad_typeid@@UAEPAXI@Z (MSVCRT.@)
330 */
332void * __thiscall MSVCRT_bad_typeid_vector_dtor(bad_typeid * _this, unsigned int flags)
333{
334 TRACE("(%p %x)\n", _this, flags);
335 if (flags & 2)
336 {
337 /* we have an array, with the number of elements stored before the first object */
338 INT_PTR i, *ptr = (INT_PTR *)_this - 1;
339
340 for (i = *ptr - 1; i >= 0; i--) MSVCRT_bad_typeid_dtor(_this + i);
342 }
343 else
344 {
346 if (flags & 1) MSVCRT_operator_delete(_this);
347 }
348 return _this;
349}
350
351/******************************************************************
352 * ??_Gbad_typeid@@UAEPAXI@Z (MSVCRT.@)
353 */
355void * __thiscall MSVCRT_bad_typeid_scalar_dtor(bad_typeid * _this, unsigned int flags)
356{
357 TRACE("(%p %x)\n", _this, flags);
359 if (flags & 1) MSVCRT_operator_delete(_this);
360 return _this;
361}
362
363/******************************************************************
364 * ??0__non_rtti_object@@QAE@ABV0@@Z (MSVCRT.@)
365 */
367__non_rtti_object * __thiscall MSVCRT___non_rtti_object_copy_ctor(__non_rtti_object * _this,
368 const __non_rtti_object * rhs)
369{
370 TRACE("(%p %p)\n", _this, rhs);
371 MSVCRT_bad_typeid_copy_ctor(_this, rhs);
372 _this->vtable = &MSVCRT___non_rtti_object_vtable;
373 return _this;
374}
375
376/******************************************************************
377 * ??0__non_rtti_object@@QAE@PBD@Z (MSVCRT.@)
378 */
380__non_rtti_object * __thiscall MSVCRT___non_rtti_object_ctor(__non_rtti_object * _this,
381 const char * name)
382{
383 TRACE("(%p %s)\n", _this, name);
384 EXCEPTION_ctor(_this, &name);
385 _this->vtable = &MSVCRT___non_rtti_object_vtable;
386 return _this;
387}
388
389/******************************************************************
390 * ??1__non_rtti_object@@UAE@XZ (MSVCRT.@)
391 */
394{
395 TRACE("(%p)\n", _this);
397}
398
399/******************************************************************
400 * ??4__non_rtti_object@@QAEAAV0@ABV0@@Z (MSVCRT.@)
401 */
403__non_rtti_object * __thiscall MSVCRT___non_rtti_object_opequals(__non_rtti_object * _this,
404 const __non_rtti_object *rhs)
405{
406 TRACE("(%p %p)\n", _this, rhs);
407 MSVCRT_bad_typeid_opequals(_this, rhs);
408 return _this;
409}
410
411/******************************************************************
412 * ??_E__non_rtti_object@@UAEPAXI@Z (MSVCRT.@)
413 */
415void * __thiscall MSVCRT___non_rtti_object_vector_dtor(__non_rtti_object * _this, unsigned int flags)
416{
417 TRACE("(%p %x)\n", _this, flags);
418 if (flags & 2)
419 {
420 /* we have an array, with the number of elements stored before the first object */
421 INT_PTR i, *ptr = (INT_PTR *)_this - 1;
422
423 for (i = *ptr - 1; i >= 0; i--) MSVCRT___non_rtti_object_dtor(_this + i);
425 }
426 else
427 {
429 if (flags & 1) MSVCRT_operator_delete(_this);
430 }
431 return _this;
432}
433
434/******************************************************************
435 * ??_G__non_rtti_object@@UAEPAXI@Z (MSVCRT.@)
436 */
438void * __thiscall MSVCRT___non_rtti_object_scalar_dtor(__non_rtti_object * _this, unsigned int flags)
439{
440 TRACE("(%p %x)\n", _this, flags);
442 if (flags & 1) MSVCRT_operator_delete(_this);
443 return _this;
444}
445
446/******************************************************************
447 * ??0bad_cast@@AAE@PBQBD@Z (MSVCRT.@)
448 * ??0bad_cast@@QAE@ABQBD@Z (MSVCRT.@)
449 */
451bad_cast * __thiscall MSVCRT_bad_cast_ctor(bad_cast * _this, const char ** name)
452{
453 TRACE("(%p %s)\n", _this, *name);
454 EXCEPTION_ctor(_this, name);
455 _this->vtable = &MSVCRT_bad_cast_vtable;
456 return _this;
457}
458
459/******************************************************************
460 * ??0bad_cast@@QAE@ABV0@@Z (MSVCRT.@)
461 */
463bad_cast * __thiscall MSVCRT_bad_cast_copy_ctor(bad_cast * _this, const bad_cast * rhs)
464{
465 TRACE("(%p %p)\n", _this, rhs);
466 MSVCRT_exception_copy_ctor(_this, rhs);
467 _this->vtable = &MSVCRT_bad_cast_vtable;
468 return _this;
469}
470
471/******************************************************************
472 * ??0bad_cast@@QAE@PBD@Z (MSVCRT.@)
473 */
475bad_cast * __thiscall MSVCRT_bad_cast_ctor_charptr(bad_cast * _this, const char * name)
476{
477 TRACE("(%p %s)\n", _this, name);
478 EXCEPTION_ctor(_this, &name);
479 _this->vtable = &MSVCRT_bad_cast_vtable;
480 return _this;
481}
482
483/******************************************************************
484 * ??_Fbad_cast@@QAEXXZ (MSVCRT.@)
485 */
487bad_cast * __thiscall MSVCRT_bad_cast_default_ctor(bad_cast * _this)
488{
489 return MSVCRT_bad_cast_ctor_charptr( _this, "bad cast" );
490}
491
492/******************************************************************
493 * ??1bad_cast@@UAE@XZ (MSVCRT.@)
494 */
497{
498 TRACE("(%p)\n", _this);
500}
501
502/******************************************************************
503 * ??4bad_cast@@QAEAAV0@ABV0@@Z (MSVCRT.@)
504 */
506bad_cast * __thiscall MSVCRT_bad_cast_opequals(bad_cast * _this, const bad_cast * rhs)
507{
508 TRACE("(%p %p)\n", _this, rhs);
509 MSVCRT_exception_opequals(_this, rhs);
510 return _this;
511}
512
513/******************************************************************
514 * ??_Ebad_cast@@UAEPAXI@Z (MSVCRT.@)
515 */
517void * __thiscall MSVCRT_bad_cast_vector_dtor(bad_cast * _this, unsigned int flags)
518{
519 TRACE("(%p %x)\n", _this, flags);
520 if (flags & 2)
521 {
522 /* we have an array, with the number of elements stored before the first object */
523 INT_PTR i, *ptr = (INT_PTR *)_this - 1;
524
525 for (i = *ptr - 1; i >= 0; i--) MSVCRT_bad_cast_dtor(_this + i);
527 }
528 else
529 {
531 if (flags & 1) MSVCRT_operator_delete(_this);
532 }
533 return _this;
534}
535
536/******************************************************************
537 * ??_Gbad_cast@@UAEPAXI@Z (MSVCRT.@)
538 */
540void * __thiscall MSVCRT_bad_cast_scalar_dtor(bad_cast * _this, unsigned int flags)
541{
542 TRACE("(%p %x)\n", _this, flags);
544 if (flags & 1) MSVCRT_operator_delete(_this);
545 return _this;
546}
547
548/******************************************************************
549 * ??8type_info@@QBEHABV0@@Z (MSVCRT.@)
550 */
553{
554 int ret = !strcmp(_this->mangled + 1, rhs->mangled + 1);
555 TRACE("(%p %p) returning %d\n", _this, rhs, ret);
556 return ret;
557}
558
559/******************************************************************
560 * ??9type_info@@QBEHABV0@@Z (MSVCRT.@)
561 */
564{
565 int ret = !!strcmp(_this->mangled + 1, rhs->mangled + 1);
566 TRACE("(%p %p) returning %d\n", _this, rhs, ret);
567 return ret;
568}
569
570/******************************************************************
571 * ?before@type_info@@QBEHABV1@@Z (MSVCRT.@)
572 */
575{
576 int ret = strcmp(_this->mangled + 1, rhs->mangled + 1) < 0;
577 TRACE("(%p %p) returning %d\n", _this, rhs, ret);
578 return ret;
579}
580
581/******************************************************************
582 * ??1type_info@@UAE@XZ (MSVCRT.@)
583 */
586{
587 TRACE("(%p)\n", _this);
588 MSVCRT_free(_this->name);
589}
590
591/******************************************************************
592 * ?name@type_info@@QBEPBDXZ (MSVCRT.@)
593 */
596{
597 if (!_this->name)
598 {
599 /* Create and set the demangled name */
600 /* Note: mangled name in type_info struct always starts with a '.', while
601 * it isn't valid for mangled name.
602 * Is this '.' really part of the mangled name, or has it some other meaning ?
603 */
604 char* name = __unDName(0, _this->mangled + 1, 0,
606 if (name)
607 {
608 unsigned int len = strlen(name);
609
610 /* It seems _unDName may leave blanks at the end of the demangled name */
611 while (len && name[--len] == ' ')
612 name[len] = '\0';
613
614 if (InterlockedCompareExchangePointer((void**)&_this->name, name, NULL))
615 {
616 /* Another thread set this member since we checked above - use it */
618 }
619 }
620 }
621 TRACE("(%p) returning %s\n", _this, _this->name);
622 return _this->name;
623}
624
625/******************************************************************
626 * ?raw_name@type_info@@QBEPBDXZ (MSVCRT.@)
627 */
630{
631 TRACE("(%p) returning %s\n", _this, _this->mangled);
632 return _this->mangled;
633}
634
635/* Unexported */
638{
639 TRACE("(%p %x)\n", _this, flags);
640 if (flags & 2)
641 {
642 /* we have an array, with the number of elements stored before the first object */
643 INT_PTR i, *ptr = (INT_PTR *)_this - 1;
644
645 for (i = *ptr - 1; i >= 0; i--) MSVCRT_type_info_dtor(_this + i);
647 }
648 else
649 {
651 if (flags & 1) MSVCRT_operator_delete(_this);
652 }
653 return _this;
654}
655
656#if _MSVCR_VER >= 80
657
658typedef exception bad_alloc;
659extern const vtable_ptr MSVCRT_bad_alloc_vtable;
660
661static void bad_alloc_ctor(bad_alloc *this, const char **name)
662{
664 this->vtable = &MSVCRT_bad_alloc_vtable;
665}
666
667/* bad_alloc class implementation */
668DEFINE_THISCALL_WRAPPER(MSVCRT_bad_alloc_copy_ctor,8)
669bad_alloc * __thiscall MSVCRT_bad_alloc_copy_ctor(bad_alloc * _this, const bad_alloc * rhs)
670{
671 TRACE("(%p %p)\n", _this, rhs);
672 MSVCRT_exception_copy_ctor(_this, rhs);
673 _this->vtable = &MSVCRT_bad_alloc_vtable;
674 return _this;
675}
676
677DEFINE_THISCALL_WRAPPER(MSVCRT_bad_alloc_dtor,4)
678void __thiscall MSVCRT_bad_alloc_dtor(bad_alloc * _this)
679{
680 TRACE("(%p)\n", _this);
682}
683
684#endif /* _MSVCR_VER >= 80 */
685
686#if _MSVCR_VER >= 100
687
688typedef struct {
689 exception e;
690 HRESULT hr;
691} scheduler_resource_allocation_error;
692extern const vtable_ptr MSVCRT_scheduler_resource_allocation_error_vtable;
693
694/* ??0scheduler_resource_allocation_error@Concurrency@@QAE@PBDJ@Z */
695/* ??0scheduler_resource_allocation_error@Concurrency@@QEAA@PEBDJ@Z */
696DEFINE_THISCALL_WRAPPER(scheduler_resource_allocation_error_ctor_name, 12)
697scheduler_resource_allocation_error* __thiscall scheduler_resource_allocation_error_ctor_name(
698 scheduler_resource_allocation_error *this, const char *name, HRESULT hr)
699{
700 TRACE("(%p %s %x)\n", this, wine_dbgstr_a(name), hr);
701 MSVCRT_exception_ctor(&this->e, &name);
702 this->e.vtable = &MSVCRT_scheduler_resource_allocation_error_vtable;
703 this->hr = hr;
704 return this;
705}
706
707/* ??0scheduler_resource_allocation_error@Concurrency@@QAE@J@Z */
708/* ??0scheduler_resource_allocation_error@Concurrency@@QEAA@J@Z */
709DEFINE_THISCALL_WRAPPER(scheduler_resource_allocation_error_ctor, 8)
710scheduler_resource_allocation_error* __thiscall scheduler_resource_allocation_error_ctor(
711 scheduler_resource_allocation_error *this, HRESULT hr)
712{
713 return scheduler_resource_allocation_error_ctor_name(this, NULL, hr);
714}
715
716DEFINE_THISCALL_WRAPPER(MSVCRT_scheduler_resource_allocation_error_copy_ctor,8)
717scheduler_resource_allocation_error* __thiscall MSVCRT_scheduler_resource_allocation_error_copy_ctor(
718 scheduler_resource_allocation_error *this,
719 const scheduler_resource_allocation_error *rhs)
720{
721 TRACE("(%p,%p)\n", this, rhs);
722
723 if (!rhs->e.do_free)
724 memcpy(this, rhs, sizeof(*this));
725 else
726 scheduler_resource_allocation_error_ctor_name(this, rhs->e.name, rhs->hr);
727 return this;
728}
729
730/* ?get_error_code@scheduler_resource_allocation_error@Concurrency@@QBEJXZ */
731/* ?get_error_code@scheduler_resource_allocation_error@Concurrency@@QEBAJXZ */
732DEFINE_THISCALL_WRAPPER(scheduler_resource_allocation_error_get_error_code, 4)
733HRESULT __thiscall scheduler_resource_allocation_error_get_error_code(
734 const scheduler_resource_allocation_error *this)
735{
736 TRACE("(%p)\n", this);
737 return this->hr;
738}
739
740DEFINE_THISCALL_WRAPPER(MSVCRT_scheduler_resource_allocation_error_dtor,4)
741void __thiscall MSVCRT_scheduler_resource_allocation_error_dtor(
742 scheduler_resource_allocation_error * this)
743{
744 TRACE("(%p)\n", this);
745 MSVCRT_exception_dtor(&this->e);
746}
747
748typedef exception improper_lock;
749extern const vtable_ptr MSVCRT_improper_lock_vtable;
750
751/* ??0improper_lock@Concurrency@@QAE@PBD@Z */
752/* ??0improper_lock@Concurrency@@QEAA@PEBD@Z */
753DEFINE_THISCALL_WRAPPER(improper_lock_ctor_str, 8)
754improper_lock* __thiscall improper_lock_ctor_str(improper_lock *this, const char *str)
755{
756 TRACE("(%p %p)\n", this, str);
758 this->vtable = &MSVCRT_improper_lock_vtable;
759 return this;
760}
761
762/* ??0improper_lock@Concurrency@@QAE@XZ */
763/* ??0improper_lock@Concurrency@@QEAA@XZ */
764DEFINE_THISCALL_WRAPPER(improper_lock_ctor, 4)
765improper_lock* __thiscall improper_lock_ctor(improper_lock *this)
766{
767 return improper_lock_ctor_str(this, NULL);
768}
769
770DEFINE_THISCALL_WRAPPER(MSVCRT_improper_lock_copy_ctor,8)
771improper_lock * __thiscall MSVCRT_improper_lock_copy_ctor(improper_lock * _this, const improper_lock * rhs)
772{
773 TRACE("(%p %p)\n", _this, rhs);
774 MSVCRT_exception_copy_ctor(_this, rhs);
775 _this->vtable = &MSVCRT_improper_lock_vtable;
776 return _this;
777}
778
779DEFINE_THISCALL_WRAPPER(MSVCRT_improper_lock_dtor,4)
780void __thiscall MSVCRT_improper_lock_dtor(improper_lock * _this)
781{
782 TRACE("(%p)\n", _this);
784}
785
786typedef exception invalid_scheduler_policy_key;
787extern const vtable_ptr MSVCRT_invalid_scheduler_policy_key_vtable;
788
789/* ??0invalid_scheduler_policy_key@Concurrency@@QAE@PBD@Z */
790/* ??0invalid_scheduler_policy_key@Concurrency@@QEAA@PEBD@Z */
791DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_key_ctor_str, 8)
792invalid_scheduler_policy_key* __thiscall invalid_scheduler_policy_key_ctor_str(
793 invalid_scheduler_policy_key *this, const char *str)
794{
795 TRACE("(%p %p)\n", this, str);
797 this->vtable = &MSVCRT_invalid_scheduler_policy_key_vtable;
798 return this;
799}
800
801/* ??0invalid_scheduler_policy_key@Concurrency@@QAE@XZ */
802/* ??0invalid_scheduler_policy_key@Concurrency@@QEAA@XZ */
803DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_key_ctor, 4)
804invalid_scheduler_policy_key* __thiscall invalid_scheduler_policy_key_ctor(
805 invalid_scheduler_policy_key *this)
806{
807 return invalid_scheduler_policy_key_ctor_str(this, NULL);
808}
809
810DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_key_copy_ctor,8)
811invalid_scheduler_policy_key * __thiscall MSVCRT_invalid_scheduler_policy_key_copy_ctor(
812 invalid_scheduler_policy_key * _this, const invalid_scheduler_policy_key * rhs)
813{
814 TRACE("(%p %p)\n", _this, rhs);
815 MSVCRT_exception_copy_ctor(_this, rhs);
816 _this->vtable = &MSVCRT_invalid_scheduler_policy_key_vtable;
817 return _this;
818}
819
820DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_key_dtor,4)
821void __thiscall MSVCRT_invalid_scheduler_policy_key_dtor(
822 invalid_scheduler_policy_key * _this)
823{
824 TRACE("(%p)\n", _this);
826}
827
828typedef exception invalid_scheduler_policy_value;
829extern const vtable_ptr MSVCRT_invalid_scheduler_policy_value_vtable;
830
831/* ??0invalid_scheduler_policy_value@Concurrency@@QAE@PBD@Z */
832/* ??0invalid_scheduler_policy_value@Concurrency@@QEAA@PEBD@Z */
833DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_value_ctor_str, 8)
834invalid_scheduler_policy_value* __thiscall invalid_scheduler_policy_value_ctor_str(
835 invalid_scheduler_policy_value *this, const char *str)
836{
837 TRACE("(%p %p)\n", this, str);
839 this->vtable = &MSVCRT_invalid_scheduler_policy_value_vtable;
840 return this;
841}
842
843/* ??0invalid_scheduler_policy_value@Concurrency@@QAE@XZ */
844/* ??0invalid_scheduler_policy_value@Concurrency@@QEAA@XZ */
845DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_value_ctor, 4)
846invalid_scheduler_policy_value* __thiscall invalid_scheduler_policy_value_ctor(
847 invalid_scheduler_policy_value *this)
848{
849 return invalid_scheduler_policy_value_ctor_str(this, NULL);
850}
851
852DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_value_copy_ctor,8)
853invalid_scheduler_policy_value * __thiscall MSVCRT_invalid_scheduler_policy_value_copy_ctor(
854 invalid_scheduler_policy_value * _this, const invalid_scheduler_policy_value * rhs)
855{
856 TRACE("(%p %p)\n", _this, rhs);
857 MSVCRT_exception_copy_ctor(_this, rhs);
858 _this->vtable = &MSVCRT_invalid_scheduler_policy_value_vtable;
859 return _this;
860}
861
862DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_value_dtor,4)
863void __thiscall MSVCRT_invalid_scheduler_policy_value_dtor(
864 invalid_scheduler_policy_value * _this)
865{
866 TRACE("(%p)\n", _this);
868}
869
870typedef exception invalid_scheduler_policy_thread_specification;
871extern const vtable_ptr MSVCRT_invalid_scheduler_policy_thread_specification_vtable;
872
873/* ??0invalid_scheduler_policy_thread_specification@Concurrency@@QAE@PBD@Z */
874/* ??0invalid_scheduler_policy_thread_specification@Concurrency@@QEAA@PEBD@Z */
875DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_thread_specification_ctor_str, 8)
876invalid_scheduler_policy_thread_specification* __thiscall invalid_scheduler_policy_thread_specification_ctor_str(
877 invalid_scheduler_policy_thread_specification *this, const char *str)
878{
879 TRACE("(%p %p)\n", this, str);
881 this->vtable = &MSVCRT_invalid_scheduler_policy_thread_specification_vtable;
882 return this;
883}
884
885/* ??0invalid_scheduler_policy_thread_specification@Concurrency@@QAE@XZ */
886/* ??0invalid_scheduler_policy_thread_specification@Concurrency@@QEAA@XZ */
887DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_thread_specification_ctor, 4)
888invalid_scheduler_policy_thread_specification* __thiscall invalid_scheduler_policy_thread_specification_ctor(
889 invalid_scheduler_policy_thread_specification *this)
890{
891 return invalid_scheduler_policy_thread_specification_ctor_str(this, NULL);
892}
893
894DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_thread_specification_copy_ctor,8)
895invalid_scheduler_policy_thread_specification * __thiscall MSVCRT_invalid_scheduler_policy_thread_specification_copy_ctor(
896 invalid_scheduler_policy_thread_specification * _this, const invalid_scheduler_policy_thread_specification * rhs)
897{
898 TRACE("(%p %p)\n", _this, rhs);
899 MSVCRT_exception_copy_ctor(_this, rhs);
900 _this->vtable = &MSVCRT_invalid_scheduler_policy_thread_specification_vtable;
901 return _this;
902}
903
904DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_thread_specification_dtor,4)
905void __thiscall MSVCRT_invalid_scheduler_policy_thread_specification_dtor(
906 invalid_scheduler_policy_thread_specification * _this)
907{
908 TRACE("(%p)\n", _this);
910}
911
912typedef exception improper_scheduler_attach;
913extern const vtable_ptr MSVCRT_improper_scheduler_attach_vtable;
914
915/* ??0improper_scheduler_attach@Concurrency@@QAE@PBD@Z */
916/* ??0improper_scheduler_attach@Concurrency@@QEAA@PEBD@Z */
917DEFINE_THISCALL_WRAPPER(improper_scheduler_attach_ctor_str, 8)
918improper_scheduler_attach* __thiscall improper_scheduler_attach_ctor_str(
919 improper_scheduler_attach *this, const char *str)
920{
921 TRACE("(%p %p)\n", this, str);
923 this->vtable = &MSVCRT_improper_scheduler_attach_vtable;
924 return this;
925}
926
927/* ??0improper_scheduler_attach@Concurrency@@QAE@XZ */
928/* ??0improper_scheduler_attach@Concurrency@@QEAA@XZ */
929DEFINE_THISCALL_WRAPPER(improper_scheduler_attach_ctor, 4)
930improper_scheduler_attach* __thiscall improper_scheduler_attach_ctor(
931 improper_scheduler_attach *this)
932{
933 return improper_scheduler_attach_ctor_str(this, NULL);
934}
935
936DEFINE_THISCALL_WRAPPER(MSVCRT_improper_scheduler_attach_copy_ctor,8)
937improper_scheduler_attach * __thiscall MSVCRT_improper_scheduler_attach_copy_ctor(
938 improper_scheduler_attach * _this, const improper_scheduler_attach * rhs)
939{
940 TRACE("(%p %p)\n", _this, rhs);
941 MSVCRT_exception_copy_ctor(_this, rhs);
942 _this->vtable = &MSVCRT_improper_scheduler_attach_vtable;
943 return _this;
944}
945
946DEFINE_THISCALL_WRAPPER(MSVCRT_improper_scheduler_attach_dtor,4)
947void __thiscall MSVCRT_improper_scheduler_attach_dtor(
948 improper_scheduler_attach * _this)
949{
950 TRACE("(%p)\n", _this);
952}
953
954typedef exception improper_scheduler_detach;
955extern const vtable_ptr MSVCRT_improper_scheduler_detach_vtable;
956
957/* ??0improper_scheduler_detach@Concurrency@@QAE@PBD@Z */
958/* ??0improper_scheduler_detach@Concurrency@@QEAA@PEBD@Z */
959DEFINE_THISCALL_WRAPPER(improper_scheduler_detach_ctor_str, 8)
960improper_scheduler_detach* __thiscall improper_scheduler_detach_ctor_str(
961 improper_scheduler_detach *this, const char *str)
962{
963 TRACE("(%p %p)\n", this, str);
965 this->vtable = &MSVCRT_improper_scheduler_detach_vtable;
966 return this;
967}
968
969/* ??0improper_scheduler_detach@Concurrency@@QAE@XZ */
970/* ??0improper_scheduler_detach@Concurrency@@QEAA@XZ */
971DEFINE_THISCALL_WRAPPER(improper_scheduler_detach_ctor, 4)
972improper_scheduler_detach* __thiscall improper_scheduler_detach_ctor(
973 improper_scheduler_detach *this)
974{
975 return improper_scheduler_detach_ctor_str(this, NULL);
976}
977
978DEFINE_THISCALL_WRAPPER(MSVCRT_improper_scheduler_detach_copy_ctor,8)
979improper_scheduler_detach * __thiscall MSVCRT_improper_scheduler_detach_copy_ctor(
980 improper_scheduler_detach * _this, const improper_scheduler_detach * rhs)
981{
982 TRACE("(%p %p)\n", _this, rhs);
983 MSVCRT_exception_copy_ctor(_this, rhs);
984 _this->vtable = &MSVCRT_improper_scheduler_detach_vtable;
985 return _this;
986}
987
988DEFINE_THISCALL_WRAPPER(MSVCRT_improper_scheduler_detach_dtor,4)
989void __thiscall MSVCRT_improper_scheduler_detach_dtor(
990 improper_scheduler_detach * _this)
991{
992 TRACE("(%p)\n", _this);
994}
995
996#endif /* _MSVCR_VER >= 100 */
997
998#ifndef _MSC_VER
999#ifndef __GNUC__
1001#endif
1002
1008#if _MSVCR_VER >= 80
1009__ASM_VTABLE(exception_old,
1012__ASM_VTABLE(bad_alloc,
1015#endif
1016__ASM_VTABLE(bad_typeid,
1019__ASM_VTABLE(bad_cast,
1022__ASM_VTABLE(__non_rtti_object,
1025#if _MSVCR_VER >= 100
1026__ASM_VTABLE(scheduler_resource_allocation_error,
1029__ASM_VTABLE(improper_lock,
1032__ASM_VTABLE(invalid_scheduler_policy_key,
1035__ASM_VTABLE(invalid_scheduler_policy_value,
1038__ASM_VTABLE(invalid_scheduler_policy_thread_specification,
1041__ASM_VTABLE(improper_scheduler_attach,
1044__ASM_VTABLE(improper_scheduler_detach,
1047#endif
1048
1049#ifndef __GNUC__
1050}
1051#endif
1052#endif /* !_MSC_VER */
1053
1054DEFINE_RTTI_DATA0( type_info, 0, ".?AVtype_info@@" )
1055#if _MSVCR_VER >= 80
1056DEFINE_RTTI_DATA0( exception, 0, ".?AVexception@std@@" )
1057DEFINE_RTTI_DATA0( exception_old, 0, ".?AVexception@@" )
1058DEFINE_RTTI_DATA1( bad_typeid, 0, &exception_rtti_base_descriptor, ".?AVbad_typeid@std@@" )
1059DEFINE_RTTI_DATA1( bad_cast, 0, &exception_rtti_base_descriptor, ".?AVbad_cast@std@@" )
1060DEFINE_RTTI_DATA2( __non_rtti_object, 0, &bad_typeid_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AV__non_rtti_object@std@@" )
1061DEFINE_RTTI_DATA1( bad_alloc, 0, &exception_rtti_base_descriptor, ".?AVbad_alloc@std@@" )
1062#else
1063DEFINE_RTTI_DATA0( exception, 0, ".?AVexception@@" )
1064DEFINE_RTTI_DATA1( bad_typeid, 0, &exception_rtti_base_descriptor, ".?AVbad_typeid@@" )
1065DEFINE_RTTI_DATA1( bad_cast, 0, &exception_rtti_base_descriptor, ".?AVbad_cast@@" )
1066DEFINE_RTTI_DATA2( __non_rtti_object, 0, &bad_typeid_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AV__non_rtti_object@@" )
1067#endif
1068#if _MSVCR_VER >= 100
1069DEFINE_RTTI_DATA1(scheduler_resource_allocation_error, 0, &exception_rtti_base_descriptor,
1070 ".?AVscheduler_resource_allocation_error@Concurrency@@")
1071DEFINE_RTTI_DATA1(improper_lock, 0, &exception_rtti_base_descriptor, ".?AVimproper_lock@Concurrency@@" )
1072DEFINE_RTTI_DATA1(invalid_scheduler_policy_key, 0, &exception_rtti_base_descriptor,
1073 ".?AVinvalid_scheduler_policy_key@Concurrency@@" )
1074DEFINE_RTTI_DATA1(invalid_scheduler_policy_value, 0, &exception_rtti_base_descriptor,
1075 ".?AVinvalid_scheduler_policy_value@Concurrency@@" )
1076DEFINE_RTTI_DATA1(invalid_scheduler_policy_thread_specification, 0, &exception_rtti_base_descriptor,
1077 ".?AVinvalid_scheduler_policy_thread_specification@Concurrency@@" )
1078DEFINE_RTTI_DATA1(improper_scheduler_attach, 0, &exception_rtti_base_descriptor,
1079 ".?AVimproper_scheduler_attach@Concurrency@@" )
1080DEFINE_RTTI_DATA1(improper_scheduler_detach, 0, &exception_rtti_base_descriptor,
1081 ".?AVimproper_scheduler_detach@Concurrency@@" )
1082#endif
1083
1084DEFINE_EXCEPTION_TYPE_INFO( exception, 0, NULL, NULL )
1085DEFINE_EXCEPTION_TYPE_INFO( bad_typeid, 1, &exception_cxx_type_info, NULL )
1086DEFINE_EXCEPTION_TYPE_INFO( bad_cast, 1, &exception_cxx_type_info, NULL )
1087DEFINE_EXCEPTION_TYPE_INFO( __non_rtti_object, 2, &bad_typeid_cxx_type_info, &exception_cxx_type_info )
1088#if _MSVCR_VER >= 80
1089DEFINE_EXCEPTION_TYPE_INFO( bad_alloc, 1, &exception_cxx_type_info, NULL )
1090#endif
1091#if _MSVCR_VER >= 100
1092DEFINE_EXCEPTION_TYPE_INFO(scheduler_resource_allocation_error, 1, &exception_cxx_type_info, NULL)
1093DEFINE_EXCEPTION_TYPE_INFO(improper_lock, 1, &exception_cxx_type_info, NULL)
1094DEFINE_EXCEPTION_TYPE_INFO(invalid_scheduler_policy_key, 1, &exception_cxx_type_info, NULL)
1095DEFINE_EXCEPTION_TYPE_INFO(invalid_scheduler_policy_value, 1, &exception_cxx_type_info, NULL)
1096DEFINE_EXCEPTION_TYPE_INFO(invalid_scheduler_policy_thread_specification, 1, &exception_cxx_type_info, NULL)
1097DEFINE_EXCEPTION_TYPE_INFO(improper_scheduler_attach, 1, &exception_cxx_type_info, NULL)
1098DEFINE_EXCEPTION_TYPE_INFO(improper_scheduler_detach, 1, &exception_cxx_type_info, NULL)
1099#endif
1100
1101void msvcrt_init_exception(void *base)
1102{
1103#ifdef __x86_64__
1104 init_type_info_rtti(base);
1105 init_exception_rtti(base);
1106#if _MSVCR_VER >= 80
1107 init_exception_old_rtti(base);
1108 init_bad_alloc_rtti(base);
1109#endif
1110 init_bad_typeid_rtti(base);
1111 init_bad_cast_rtti(base);
1112 init___non_rtti_object_rtti(base);
1113#if _MSVCR_VER >= 100
1114 init_scheduler_resource_allocation_error_rtti(base);
1115 init_improper_lock_rtti(base);
1116 init_invalid_scheduler_policy_key_rtti(base);
1117 init_invalid_scheduler_policy_value_rtti(base);
1118 init_invalid_scheduler_policy_thread_specification_rtti(base);
1119 init_improper_scheduler_attach_rtti(base);
1120 init_improper_scheduler_detach_rtti(base);
1121#endif
1122
1123 init_exception_cxx(base);
1124 init_bad_typeid_cxx(base);
1125 init_bad_cast_cxx(base);
1126 init___non_rtti_object_cxx(base);
1127#if _MSVCR_VER >= 80
1128 init_bad_alloc_cxx(base);
1129#endif
1130#if _MSVCR_VER >= 100
1131 init_scheduler_resource_allocation_error_cxx(base);
1132 init_improper_lock_cxx(base);
1133 init_invalid_scheduler_policy_key_cxx(base);
1134 init_invalid_scheduler_policy_value_cxx(base);
1135 init_invalid_scheduler_policy_thread_specification_cxx(base);
1136 init_improper_scheduler_attach_cxx(base);
1137 init_improper_scheduler_detach_cxx(base);
1138#endif
1139#endif
1140}
1141
1142#if _MSVCR_VER >= 80
1143void throw_exception(exception_type et, HRESULT hr, const char *str)
1144{
1145 switch(et) {
1146 case EXCEPTION_BAD_ALLOC: {
1147 bad_alloc e;
1148 bad_alloc_ctor(&e, &str);
1149 _CxxThrowException(&e, &bad_alloc_exception_type);
1150 }
1151#if _MSVCR_VER >= 100
1152 case EXCEPTION_SCHEDULER_RESOURCE_ALLOCATION_ERROR: {
1153 scheduler_resource_allocation_error e;
1154 scheduler_resource_allocation_error_ctor_name(&e, str, hr);
1155 _CxxThrowException(&e.e, &scheduler_resource_allocation_error_exception_type);
1156 }
1157 case EXCEPTION_IMPROPER_LOCK: {
1158 improper_lock e;
1159 improper_lock_ctor_str(&e, str);
1160 _CxxThrowException(&e, &improper_lock_exception_type);
1161 }
1162 case EXCEPTION_INVALID_SCHEDULER_POLICY_KEY: {
1163 invalid_scheduler_policy_key e;
1164 invalid_scheduler_policy_key_ctor_str(&e, str);
1165 _CxxThrowException(&e, &invalid_scheduler_policy_key_exception_type);
1166 }
1167 case EXCEPTION_INVALID_SCHEDULER_POLICY_VALUE: {
1168 invalid_scheduler_policy_value e;
1169 invalid_scheduler_policy_value_ctor_str(&e, str);
1170 _CxxThrowException(&e, &invalid_scheduler_policy_value_exception_type);
1171 }
1172 case EXCEPTION_INVALID_SCHEDULER_POLICY_THREAD_SPECIFICATION: {
1173 invalid_scheduler_policy_thread_specification e;
1174 invalid_scheduler_policy_thread_specification_ctor_str(&e, str);
1175 _CxxThrowException(&e, &invalid_scheduler_policy_thread_specification_exception_type);
1176 }
1177 case EXCEPTION_IMPROPER_SCHEDULER_ATTACH: {
1178 improper_scheduler_attach e;
1179 improper_scheduler_attach_ctor_str(&e, str);
1180 _CxxThrowException(&e, &improper_scheduler_attach_exception_type);
1181 }
1182 case EXCEPTION_IMPROPER_SCHEDULER_DETACH: {
1183 improper_scheduler_detach e;
1184 improper_scheduler_detach_ctor_str(&e, str);
1185 _CxxThrowException(&e, &improper_scheduler_detach_exception_type);
1186 }
1187#endif
1188 }
1189}
1190#endif
1191
1192/******************************************************************
1193 * ?set_terminate@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
1194 *
1195 * Install a handler to be called when terminate() is called.
1196 *
1197 * PARAMS
1198 * func [I] Handler function to install
1199 *
1200 * RETURNS
1201 * The previously installed handler function, if any.
1202 */
1203MSVCRT_terminate_function CDECL MSVCRT_set_terminate(MSVCRT_terminate_function func)
1204{
1205 thread_data_t *data = msvcrt_get_thread_data();
1206 MSVCRT_terminate_function previous = data->terminate_handler;
1207 TRACE("(%p) returning %p\n",func,previous);
1209 return previous;
1210}
1211
1212/******************************************************************
1213 * _get_terminate (MSVCRT.@)
1214 */
1216{
1218 TRACE("returning %p\n", data->terminate_handler);
1219 return data->terminate_handler;
1220}
1221
1222/******************************************************************
1223 * ?set_unexpected@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
1224 *
1225 * Install a handler to be called when unexpected() is called.
1226 *
1227 * PARAMS
1228 * func [I] Handler function to install
1229 *
1230 * RETURNS
1231 * The previously installed handler function, if any.
1232 */
1234{
1236 MSVCRT_unexpected_function previous = data->unexpected_handler;
1237 TRACE("(%p) returning %p\n",func,previous);
1238 data->unexpected_handler = func;
1239 return previous;
1240}
1241
1242/******************************************************************
1243 * _get_unexpected (MSVCRT.@)
1244 */
1246{
1248 TRACE("returning %p\n", data->unexpected_handler);
1249 return data->unexpected_handler;
1250}
1251
1252/******************************************************************
1253 * ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z (MSVCRT.@)
1254 */
1256{
1258 MSVCRT__se_translator_function previous = data->se_translator;
1259 TRACE("(%p) returning %p\n",func,previous);
1260 data->se_translator = func;
1261 return previous;
1262}
1263
1264/******************************************************************
1265 * ?terminate@@YAXXZ (MSVCRT.@)
1266 *
1267 * Default handler for an unhandled exception.
1268 *
1269 * PARAMS
1270 * None.
1271 *
1272 * RETURNS
1273 * This function does not return. Either control resumes from any
1274 * handler installed by calling set_terminate(), or (by default) abort()
1275 * is called.
1276 */
1278{
1280 if (data->terminate_handler) data->terminate_handler();
1281 MSVCRT_abort();
1282}
1283
1284/******************************************************************
1285 * ?unexpected@@YAXXZ (MSVCRT.@)
1286 */
1288{
1290 if (data->unexpected_handler) data->unexpected_handler();
1292}
1293
1294
1295/******************************************************************
1296 * __RTtypeid (MSVCRT.@)
1297 *
1298 * Retrieve the Run Time Type Information (RTTI) for a C++ object.
1299 *
1300 * PARAMS
1301 * cppobj [I] C++ object to get type information for.
1302 *
1303 * RETURNS
1304 * Success: A type_info object describing cppobj.
1305 * Failure: If the object to be cast has no RTTI, a __non_rtti_object
1306 * exception is thrown. If cppobj is NULL, a bad_typeid exception
1307 * is thrown. In either case, this function does not return.
1308 *
1309 * NOTES
1310 * This function is usually called by compiler generated code as a result
1311 * of using one of the C++ dynamic cast statements.
1312 */
1313#ifndef __x86_64__
1315{
1316 const type_info *ret;
1317
1318 if (!cppobj)
1319 {
1320 bad_typeid e;
1321 MSVCRT_bad_typeid_ctor( &e, "Attempted a typeid of NULL pointer!" );
1322 _CxxThrowException( &e, &bad_typeid_exception_type );
1323 return NULL;
1324 }
1325
1326 __TRY
1327 {
1328 const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
1329 ret = obj_locator->type_descriptor;
1330 }
1332 {
1333 __non_rtti_object e;
1334 MSVCRT___non_rtti_object_ctor( &e, "Bad read pointer - no RTTI data!" );
1335 _CxxThrowException( &e, &__non_rtti_object_exception_type );
1336 return NULL;
1337 }
1338 __ENDTRY
1339 return ret;
1340}
1341
1342#else
1343
1344const type_info* CDECL MSVCRT___RTtypeid(void *cppobj)
1345{
1346 const type_info *ret;
1347
1348 if (!cppobj)
1349 {
1350 bad_typeid e;
1351 MSVCRT_bad_typeid_ctor( &e, "Attempted a typeid of NULL pointer!" );
1352 _CxxThrowException( &e, &bad_typeid_exception_type );
1353 return NULL;
1354 }
1355
1356 __TRY
1357 {
1358 const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
1359 char *base;
1360
1361 if(obj_locator->signature == 0)
1362 base = RtlPcToFileHeader((void*)obj_locator, (void**)&base);
1363 else
1364 base = (char*)obj_locator - obj_locator->object_locator;
1365
1366 ret = (type_info*)(base + obj_locator->type_descriptor);
1367 }
1369 {
1370 __non_rtti_object e;
1371 MSVCRT___non_rtti_object_ctor( &e, "Bad read pointer - no RTTI data!" );
1372 _CxxThrowException( &e, &__non_rtti_object_exception_type );
1373 return NULL;
1374 }
1375 __ENDTRY
1376 return ret;
1377}
1378#endif
1379
1380/******************************************************************
1381 * __RTDynamicCast (MSVCRT.@)
1382 *
1383 * Dynamically cast a C++ object to one of its base classes.
1384 *
1385 * PARAMS
1386 * cppobj [I] Any C++ object to cast
1387 * unknown [I] Reserved, set to 0
1388 * src [I] type_info object describing cppobj
1389 * dst [I] type_info object describing the base class to cast to
1390 * do_throw [I] TRUE = throw an exception if the cast fails, FALSE = don't
1391 *
1392 * RETURNS
1393 * Success: The address of cppobj, cast to the object described by dst.
1394 * Failure: NULL, If the object to be cast has no RTTI, or dst is not a
1395 * valid cast for cppobj. If do_throw is TRUE, a bad_cast exception
1396 * is thrown and this function does not return.
1397 *
1398 * NOTES
1399 * This function is usually called by compiler generated code as a result
1400 * of using one of the C++ dynamic cast statements.
1401 */
1402#ifndef __x86_64__
1403void* CDECL MSVCRT___RTDynamicCast(void *cppobj, int unknown,
1405 int do_throw)
1406{
1407 void *ret;
1408
1409 if (!cppobj) return NULL;
1410
1411 TRACE("obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)\n",
1412 cppobj, unknown, src, dbgstr_type_info(src), dst, dbgstr_type_info(dst), do_throw);
1413
1414 /* To cast an object at runtime:
1415 * 1.Find out the true type of the object from the typeinfo at vtable[-1]
1416 * 2.Search for the destination type in the class hierarchy
1417 * 3.If destination type is found, return base object address + dest offset
1418 * Otherwise, fail the cast
1419 *
1420 * FIXME: the unknown parameter doesn't seem to be used for anything
1421 */
1422 __TRY
1423 {
1424 int i;
1425 const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
1426 const rtti_object_hierarchy *obj_bases = obj_locator->type_hierarchy;
1427 const rtti_base_descriptor * const* base_desc = obj_bases->base_classes->bases;
1428
1429 if (TRACE_ON(msvcrt)) dump_obj_locator(obj_locator);
1430
1431 ret = NULL;
1432 for (i = 0; i < obj_bases->array_len; i++)
1433 {
1434 const type_info *typ = base_desc[i]->type_descriptor;
1435
1436 if (!strcmp(typ->mangled, dst->mangled))
1437 {
1438 /* compute the correct this pointer for that base class */
1439 void *this_ptr = (char *)cppobj - obj_locator->base_class_offset;
1440 ret = get_this_pointer( &base_desc[i]->offsets, this_ptr );
1441 break;
1442 }
1443 }
1444 /* VC++ sets do_throw to 1 when the result of a dynamic_cast is assigned
1445 * to a reference, since references cannot be NULL.
1446 */
1447 if (!ret && do_throw)
1448 {
1449 const char *msg = "Bad dynamic_cast!";
1450 bad_cast e;
1452 _CxxThrowException( &e, &bad_cast_exception_type );
1453 }
1454 }
1456 {
1457 __non_rtti_object e;
1458 MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" );
1459 _CxxThrowException( &e, &__non_rtti_object_exception_type );
1460 return NULL;
1461 }
1462 __ENDTRY
1463 return ret;
1464}
1465
1466#else
1467
1468void* CDECL MSVCRT___RTDynamicCast(void *cppobj, int unknown,
1470 int do_throw)
1471{
1472 void *ret;
1473
1474 if (!cppobj) return NULL;
1475
1476 TRACE("obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)\n",
1477 cppobj, unknown, src, dbgstr_type_info(src), dst, dbgstr_type_info(dst), do_throw);
1478
1479 __TRY
1480 {
1481 int i;
1482 const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
1483 const rtti_object_hierarchy *obj_bases;
1484 const rtti_base_array *base_array;
1485 char *base;
1486
1487 if (TRACE_ON(msvcrt)) dump_obj_locator(obj_locator);
1488
1489 if(obj_locator->signature == 0)
1490 base = RtlPcToFileHeader((void*)obj_locator, (void**)&base);
1491 else
1492 base = (char*)obj_locator - obj_locator->object_locator;
1493
1494 obj_bases = (const rtti_object_hierarchy*)(base + obj_locator->type_hierarchy);
1495 base_array = (const rtti_base_array*)(base + obj_bases->base_classes);
1496
1497 ret = NULL;
1498 for (i = 0; i < obj_bases->array_len; i++)
1499 {
1500 const rtti_base_descriptor *base_desc = (const rtti_base_descriptor*)(base + base_array->bases[i]);
1501 const type_info *typ = (const type_info*)(base + base_desc->type_descriptor);
1502
1503 if (!strcmp(typ->mangled, dst->mangled))
1504 {
1505 void *this_ptr = (char *)cppobj - obj_locator->base_class_offset;
1506 ret = get_this_pointer( &base_desc->offsets, this_ptr );
1507 break;
1508 }
1509 }
1510 if (!ret && do_throw)
1511 {
1512 const char *msg = "Bad dynamic_cast!";
1513 bad_cast e;
1515 _CxxThrowException( &e, &bad_cast_exception_type );
1516 }
1517 }
1519 {
1520 __non_rtti_object e;
1521 MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" );
1522 _CxxThrowException( &e, &__non_rtti_object_exception_type );
1523 return NULL;
1524 }
1525 __ENDTRY
1526 return ret;
1527}
1528#endif
1529
1530
1531/******************************************************************
1532 * __RTCastToVoid (MSVCRT.@)
1533 *
1534 * Dynamically cast a C++ object to a void*.
1535 *
1536 * PARAMS
1537 * cppobj [I] The C++ object to cast
1538 *
1539 * RETURNS
1540 * Success: The base address of the object as a void*.
1541 * Failure: NULL, if cppobj is NULL or has no RTTI.
1542 *
1543 * NOTES
1544 * This function is usually called by compiler generated code as a result
1545 * of using one of the C++ dynamic cast statements.
1546 */
1547void* CDECL MSVCRT___RTCastToVoid(void *cppobj)
1548{
1549 void *ret;
1550
1551 if (!cppobj) return NULL;
1552
1553 __TRY
1554 {
1555 const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
1556 ret = (char *)cppobj - obj_locator->base_class_offset;
1557 }
1559 {
1560 __non_rtti_object e;
1561 MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" );
1562 _CxxThrowException( &e, &__non_rtti_object_exception_type );
1563 return NULL;
1564 }
1565 __ENDTRY
1566 return ret;
1567}
1568
1569
1570/*********************************************************************
1571 * _CxxThrowException (MSVCRT.@)
1572 */
1573#ifndef __x86_64__
1575{
1576 ULONG_PTR args[3];
1577
1579 args[1] = (ULONG_PTR)object;
1580 args[2] = (ULONG_PTR)type;
1582}
1583#else
1585{
1586 ULONG_PTR args[4];
1587
1589 args[1] = (ULONG_PTR)object;
1590 args[2] = (ULONG_PTR)type;
1591 RtlPcToFileHeader( (void*)type, (void**)&args[3]);
1593}
1594#endif
1595
1596#if _MSVCR_VER >= 80
1597
1598/*********************************************************************
1599 * ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z
1600 * ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z
1601 */
1602#ifndef __x86_64__
1604{
1605 int ret = -1;
1606
1607 TRACE("(%p %p)\n", ti, ep);
1608
1609 __TRY
1610 {
1612
1613 if (rec->ExceptionCode==CXX_EXCEPTION && rec->NumberParameters==3 &&
1617 {
1618 const cxx_type_info_table *tit = ((cxx_exception_type*)rec->ExceptionInformation[2])->type_info_table;
1619 int i;
1620
1621 for (i=0; i<tit->count; i++) {
1622 if (ti==tit->info[i]->type_info || !strcmp(ti->mangled, tit->info[i]->type_info->mangled))
1623 {
1624 ret = 1;
1625 break;
1626 }
1627 }
1628
1629 if (i == tit->count)
1630 ret = 0;
1631 }
1632 }
1634 __ENDTRY
1635
1636 if(ret == -1)
1638 return ret;
1639}
1640#else
1642{
1643 int ret = -1;
1644
1645 TRACE("(%p %p)\n", ti, ep);
1646
1647 __TRY
1648 {
1650
1651 if (rec->ExceptionCode==CXX_EXCEPTION && rec->NumberParameters==4 &&
1655 {
1658 int i;
1659
1660 for (i=0; i<tit->count; i++) {
1661 const cxx_type_info *cti = (const cxx_type_info*)(rec->ExceptionInformation[3]+tit->info[i]);
1662 const type_info *except_ti = (const type_info*)(rec->ExceptionInformation[3]+cti->type_info);
1663 if (ti==except_ti || !strcmp(ti->mangled, except_ti->mangled))
1664 {
1665 ret = 1;
1666 break;
1667 }
1668 }
1669
1670 if (i == tit->count)
1671 ret = 0;
1672 }
1673 }
1675 __ENDTRY
1676
1677 if(ret == -1)
1679 return ret;
1680}
1681#endif
1682
1683/*********************************************************************
1684 * __clean_type_info_names_internal (MSVCR80.@)
1685 */
1686void CDECL __clean_type_info_names_internal(void *p)
1687{
1688 FIXME("(%p) stub\n", p);
1689}
1690
1691/*********************************************************************
1692 * ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z (MSVCR100.@)
1693 */
1694DEFINE_THISCALL_WRAPPER(type_info_name_internal_method,8)
1695const char * __thiscall type_info_name_internal_method(type_info * _this, struct __type_info_node *node)
1696{
1697 static int once;
1698 if (node && !once++) FIXME("type_info_node parameter ignored\n");
1699
1700 return MSVCRT_type_info_name(_this);
1701}
1702
1703#endif /* _MSVCR_VER >= 80 */
1704
1705/* std::exception_ptr class helpers */
1706typedef struct
1707{
1709 int *ref; /* not binary compatible with native msvcr100 */
1711
1712#if _MSVCR_VER >= 100
1713
1714/*********************************************************************
1715 * ?__ExceptionPtrCreate@@YAXPAX@Z
1716 * ?__ExceptionPtrCreate@@YAXPEAX@Z
1717 */
1718void __cdecl __ExceptionPtrCreate(exception_ptr *ep)
1719{
1720 TRACE("(%p)\n", ep);
1721
1722 ep->rec = NULL;
1723 ep->ref = NULL;
1724}
1725
1726#if defined(__i386__) && !defined(__MINGW32__)
1727extern void call_dtor(const cxx_exception_type *type, void *func, void *object);
1728
1729__ASM_GLOBAL_FUNC( call_dtor,
1730 "movl 12(%esp),%ecx\n\t"
1731 "call *8(%esp)\n\t"
1732 "ret" );
1733#elif __x86_64__
1734static inline void call_dtor(const cxx_exception_type *type, unsigned int dtor, void *object)
1735{
1736 char *base = RtlPcToFileHeader((void*)type, (void**)&base);
1737 void (__cdecl *func)(void*) = (void*)(base + dtor);
1738 func(object);
1739}
1740#else
1741#define call_dtor(type, func, object) ((void (__thiscall*)(void*))(func))(object)
1742#endif
1743
1744/*********************************************************************
1745 * ?__ExceptionPtrDestroy@@YAXPAX@Z
1746 * ?__ExceptionPtrDestroy@@YAXPEAX@Z
1747 */
1748void __cdecl __ExceptionPtrDestroy(exception_ptr *ep)
1749{
1750 TRACE("(%p)\n", ep);
1751
1752 if (!ep->rec)
1753 return;
1754
1755 if (!InterlockedDecrement(ep->ref))
1756 {
1757 if (ep->rec->ExceptionCode == CXX_EXCEPTION)
1758 {
1759 const cxx_exception_type *type = (void*)ep->rec->ExceptionInformation[2];
1760 void *obj = (void*)ep->rec->ExceptionInformation[1];
1761
1762 if (type && type->destructor) call_dtor(type, type->destructor, obj);
1764 }
1765
1766 HeapFree(GetProcessHeap(), 0, ep->rec);
1767 HeapFree(GetProcessHeap(), 0, ep->ref);
1768 }
1769}
1770
1771/*********************************************************************
1772 * ?__ExceptionPtrCopy@@YAXPAXPBX@Z
1773 * ?__ExceptionPtrCopy@@YAXPEAXPEBX@Z
1774 */
1775void __cdecl __ExceptionPtrCopy(exception_ptr *ep, const exception_ptr *copy)
1776{
1777 TRACE("(%p %p)\n", ep, copy);
1778
1779 /* don't destroy object stored in ep */
1780 *ep = *copy;
1781 if (ep->ref)
1783}
1784
1785/*********************************************************************
1786 * ?__ExceptionPtrAssign@@YAXPAXPBX@Z
1787 * ?__ExceptionPtrAssign@@YAXPEAXPEBX@Z
1788 */
1789void __cdecl __ExceptionPtrAssign(exception_ptr *ep, const exception_ptr *assign)
1790{
1791 TRACE("(%p %p)\n", ep, assign);
1792
1793 /* don't destroy object stored in ep */
1794 if (ep->ref)
1796
1797 *ep = *assign;
1798 if (ep->ref)
1800}
1801
1802#endif /* _MSVCR_VER >= 100 */
1803
1804/*********************************************************************
1805 * ?__ExceptionPtrRethrow@@YAXPBX@Z
1806 * ?__ExceptionPtrRethrow@@YAXPEBX@Z
1807 */
1809{
1810 TRACE("(%p)\n", ep);
1811
1812 if (!ep->rec)
1813 {
1814 static const char *exception_msg = "bad exception";
1815 exception e;
1816
1817 MSVCRT_exception_ctor(&e, &exception_msg);
1818 _CxxThrowException(&e, &exception_exception_type);
1819 return;
1820 }
1821
1824}
1825
1826#if _MSVCR_VER >= 100
1827
1828#ifdef __i386__
1829extern void call_copy_ctor( void *func, void *this, void *src, int has_vbase );
1830#else
1831static inline void call_copy_ctor( void *func, void *this, void *src, int has_vbase )
1832{
1833 TRACE( "calling copy ctor %p object %p src %p\n", func, this, src );
1834 if (has_vbase)
1835 ((void (__cdecl*)(void*, void*, BOOL))func)(this, src, 1);
1836 else
1837 ((void (__cdecl*)(void*, void*))func)(this, src);
1838}
1839#endif
1840
1841/*********************************************************************
1842 * ?__ExceptionPtrCurrentException@@YAXPAX@Z
1843 * ?__ExceptionPtrCurrentException@@YAXPEAX@Z
1844 */
1845#ifndef __x86_64__
1846void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep)
1847{
1848 EXCEPTION_RECORD *rec = msvcrt_get_thread_data()->exc_record;
1849
1850 TRACE("(%p)\n", ep);
1851
1852 if (!rec)
1853 {
1854 ep->rec = NULL;
1855 ep->ref = NULL;
1856 return;
1857 }
1858
1859 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1860 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1861
1862 *ep->rec = *rec;
1863 *ep->ref = 1;
1864
1865 if (ep->rec->ExceptionCode == CXX_EXCEPTION)
1866 {
1867 const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2];
1868 const cxx_type_info *ti;
1869 void **data, *obj;
1870
1871 ti = et->type_info_table->info[0];
1872 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1873
1874 obj = (void*)ep->rec->ExceptionInformation[1];
1875 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1876 {
1877 memcpy(data, obj, ti->size);
1878 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1879 }
1880 else if (ti->copy_ctor)
1881 {
1882 call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj),
1883 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS);
1884 }
1885 else
1886 memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size);
1888 }
1889 return;
1890}
1891#else
1892void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep)
1893{
1894 EXCEPTION_RECORD *rec = msvcrt_get_thread_data()->exc_record;
1895
1896 TRACE("(%p)\n", ep);
1897
1898 if (!rec)
1899 {
1900 ep->rec = NULL;
1901 ep->ref = NULL;
1902 return;
1903 }
1904
1905 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1906 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1907
1908 *ep->rec = *rec;
1909 *ep->ref = 1;
1910
1911 if (ep->rec->ExceptionCode == CXX_EXCEPTION)
1912 {
1913 const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2];
1914 const cxx_type_info *ti;
1915 void **data, *obj;
1916 char *base = RtlPcToFileHeader((void*)et, (void**)&base);
1917
1918 ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + et->type_info_table))->info[0]);
1919 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1920
1921 obj = (void*)ep->rec->ExceptionInformation[1];
1922 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1923 {
1924 memcpy(data, obj, ti->size);
1925 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1926 }
1927 else if (ti->copy_ctor)
1928 {
1929 call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj),
1930 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS);
1931 }
1932 else
1933 memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size);
1935 }
1936 return;
1937}
1938#endif
1939
1940#endif /* _MSVCR_VER >= 100 */
1941
1942#if _MSVCR_VER >= 110
1943/*********************************************************************
1944 * ?__ExceptionPtrToBool@@YA_NPBX@Z
1945 * ?__ExceptionPtrToBool@@YA_NPEBX@Z
1946 */
1947MSVCRT_bool __cdecl __ExceptionPtrToBool(exception_ptr *ep)
1948{
1949 return !!ep->rec;
1950}
1951#endif
1952
1953#if _MSVCR_VER >= 100
1954
1955/*********************************************************************
1956 * ?__ExceptionPtrCopyException@@YAXPAXPBX1@Z
1957 * ?__ExceptionPtrCopyException@@YAXPEAXPEBX1@Z
1958 */
1959#ifndef __x86_64__
1960void __cdecl __ExceptionPtrCopyException(exception_ptr *ep,
1961 exception *object, const cxx_exception_type *type)
1962{
1963 const cxx_type_info *ti;
1964 void **data;
1965
1966 __ExceptionPtrDestroy(ep);
1967
1968 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1969 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1970 *ep->ref = 1;
1971
1972 memset(ep->rec, 0, sizeof(EXCEPTION_RECORD));
1975 ep->rec->NumberParameters = 3;
1978
1979 ti = type->type_info_table->info[0];
1980 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1981 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1982 {
1983 memcpy(data, object, ti->size);
1984 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1985 }
1986 else if (ti->copy_ctor)
1987 {
1988 call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, object),
1990 }
1991 else
1992 memcpy(data, get_this_pointer(&ti->offsets, object), ti->size);
1994}
1995#else
1996void __cdecl __ExceptionPtrCopyException(exception_ptr *ep,
1997 exception *object, const cxx_exception_type *type)
1998{
1999 const cxx_type_info *ti;
2000 void **data;
2001 char *base;
2002
2003 RtlPcToFileHeader((void*)type, (void**)&base);
2004 __ExceptionPtrDestroy(ep);
2005
2006 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
2007 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
2008 *ep->ref = 1;
2009
2010 memset(ep->rec, 0, sizeof(EXCEPTION_RECORD));
2013 ep->rec->NumberParameters = 4;
2017
2018 ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + type->type_info_table))->info[0]);
2019 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
2020 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
2021 {
2022 memcpy(data, object, ti->size);
2023 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
2024 }
2025 else if (ti->copy_ctor)
2026 {
2027 call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, object),
2029 }
2030 else
2031 memcpy(data, get_this_pointer(&ti->offsets, object), ti->size);
2033}
2034#endif
2035
2036MSVCRT_bool __cdecl __ExceptionPtrCompare(const exception_ptr *ep1, const exception_ptr *ep2)
2037{
2038 return ep1->rec == ep2->rec;
2039}
2040
2041#endif /* _MSVCR_VER >= 100 */
2042
2043#if _MSVCR_VER >= 80
2044void* __cdecl __AdjustPointer(void *obj, const this_ptr_offsets *off)
2045{
2046 return get_this_pointer(off, obj);
2047}
2048#endif
2049
2050#if _MSVCR_VER >= 140
2051
2052typedef struct
2053{
2054 char *name;
2055 char mangled[1];
2056} type_info140;
2057
2058typedef struct
2059{
2061 char name[1];
2062} type_info_entry;
2063
2064static void* CDECL type_info_entry_malloc(MSVCRT_size_t size)
2065{
2066 type_info_entry *ret = MSVCRT_malloc(FIELD_OFFSET(type_info_entry, name) + size);
2067 return ret->name;
2068}
2069
2070static void CDECL type_info_entry_free(void *ptr)
2071{
2072 ptr = (char*)ptr - FIELD_OFFSET(type_info_entry, name);
2074}
2075
2076/******************************************************************
2077 * __std_type_info_compare (UCRTBASE.@)
2078 */
2079int CDECL MSVCRT_type_info_compare(const type_info140 *l, const type_info140 *r)
2080{
2081 int ret;
2082
2083 if (l == r) ret = 0;
2084 else ret = MSVCRT_strcmp(l->mangled + 1, r->mangled + 1);
2085 TRACE("(%p %p) returning %d\n", l, r, ret);
2086 return ret;
2087}
2088
2089/******************************************************************
2090 * __std_type_info_name (UCRTBASE.@)
2091 */
2092const char* CDECL MSVCRT_type_info_name_list(type_info140 *ti, SLIST_HEADER *header)
2093{
2094 if (!ti->name)
2095 {
2096 char* name = __unDName(0, ti->mangled + 1, 0,
2097 type_info_entry_malloc, type_info_entry_free, UNDNAME_NO_ARGUMENTS | UNDNAME_32_BIT_DECODE);
2098 if (name)
2099 {
2100 unsigned int len = strlen(name);
2101
2102 while (len && name[--len] == ' ')
2103 name[len] = '\0';
2104
2105 if (InterlockedCompareExchangePointer((void**)&ti->name, name, NULL))
2106 {
2107 type_info_entry_free(name);
2108 }
2109 else
2110 {
2111 type_info_entry *entry = (type_info_entry*)(name-FIELD_OFFSET(type_info_entry, name));
2113 }
2114 }
2115 }
2116 TRACE("(%p) returning %s\n", ti, ti->name);
2117 return ti->name;
2118}
2119
2120/******************************************************************
2121 * __std_type_info_destroy_list (UCRTBASE.@)
2122 */
2123void CDECL MSVCRT_type_info_destroy_list(SLIST_HEADER *header)
2124{
2125 SLIST_ENTRY *cur, *next;
2126
2127 TRACE("(%p)\n", header);
2128
2130 {
2131 next = cur->Next;
2133 }
2134}
2135
2136/******************************************************************
2137 * __std_type_info_hash (UCRTBASE.@)
2138 */
2139MSVCRT_size_t CDECL MSVCRT_type_info_hash(const type_info140 *ti)
2140{
2141 MSVCRT_size_t hash, fnv_prime;
2142 const char *p;
2143
2144#ifdef _WIN64
2145 hash = 0xcbf29ce484222325;
2146 fnv_prime = 0x100000001b3;
2147#else
2148 hash = 0x811c9dc5;
2149 fnv_prime = 0x1000193;
2150#endif
2151
2152 TRACE("(%p)->%s\n", ti, ti->mangled);
2153
2154 for(p = ti->mangled+1; *p; p++) {
2155 hash ^= *p;
2156 hash *= fnv_prime;
2157 }
2158
2159#ifdef _WIN64
2160 hash ^= hash >> 32;
2161#endif
2162
2163 return hash;
2164}
2165
2166#endif /* _MSVCR_VER >= 140 */
2167
2168#if _MSVCR_VER >= 100
2169
2170enum ConcRT_EventType
2171{
2172 CONCRT_EVENT_GENERIC,
2173 CONCRT_EVENT_START,
2174 CONCRT_EVENT_END,
2175 CONCRT_EVENT_BLOCK,
2176 CONCRT_EVENT_UNBLOCK,
2177 CONCRT_EVENT_YIELD,
2178 CONCRT_EVENT_ATTACH,
2179 CONCRT_EVENT_DETACH
2180};
2181
2182/* ?_Trace_ppl_function@Concurrency@@YAXABU_GUID@@EW4ConcRT_EventType@1@@Z */
2183/* ?_Trace_ppl_function@Concurrency@@YAXAEBU_GUID@@EW4ConcRT_EventType@1@@Z */
2184void __cdecl Concurrency__Trace_ppl_function(const GUID *guid, unsigned char level, enum ConcRT_EventType type)
2185{
2186 FIXME("(%s %u %i) stub\n", debugstr_guid(guid), level, type);
2187}
2188
2189#endif /* _MSVCR_VER >= 100 */
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define __cdecl
Definition: accygwin.h:79
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
#define FIXME(fmt,...)
Definition: debug.h:111
r l[0]
Definition: byte_order.h:167
return
Definition: dirsup.c:529
FxCollectionEntry * Next(VOID)
#define __ASM_VTABLE(name, funcs)
Definition: cxx.h:37
#define VTABLE_ADD_FUNC(name)
Definition: cxx.h:35
#define DEFINE_RTTI_DATA0(name, off, mangled_name)
Definition: cxx.h:161
#define UNDNAME_32_BIT_DECODE
Definition: dbghelp.h:1264
#define UNDNAME_NO_ARGUMENTS
Definition: dbghelp.h:1266
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
PVOID NTAPI RtlPcToFileHeader(IN PVOID PcValue, PVOID *BaseOfImage)
Definition: libsupp.c:659
static WCHAR unknown[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1605
static const WCHAR empty[]
Definition: main.c:47
#define CDECL
Definition: compat.h:29
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define __TRY
Definition: compat.h:80
#define TRACE_ON(x)
Definition: compat.h:75
#define HeapFree(x, y, z)
Definition: compat.h:735
#define __ENDTRY
Definition: compat.h:82
#define __EXCEPT_PAGE_FAULT
Definition: compat.h:81
VOID WINAPI RaiseException(IN DWORD dwExceptionCode, IN DWORD dwExceptionFlags, IN DWORD nNumberOfArguments, IN CONST ULONG_PTR *lpArguments OPTIONAL)
Definition: except.c:700
unsigned char
Definition: typeof.h:29
#define ULONG_PTR
Definition: config.h:101
static const FxOffsetAndName offsets[]
FxCollectionEntry * cur
GLint level
Definition: gl.h:1546
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizeiptr size
Definition: glext.h:5919
GLenum func
Definition: glext.h:6028
GLdouble n
Definition: glext.h:7729
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
void(__cdecl * terminate_handler)(void)
Definition: eh.h:20
_CRTIMP int __cdecl _is_exception_typeof(const type_info &_Type, struct _EXCEPTION_POINTERS *_ExceptionPtr)
#define CXX_EXCEPTION
Definition: cppexcept.h:27
static const char * dbgstr_type_info(const type_info *info)
Definition: cppexcept.h:155
#define CLASS_IS_SIMPLE_TYPE
Definition: cppexcept.h:127
#define CXX_FRAME_MAGIC_VC7
Definition: cppexcept.h:25
#define CXX_FRAME_MAGIC_VC6
Definition: cppexcept.h:24
#define CLASS_HAS_VIRTUAL_BASE_CLASS
Definition: cppexcept.h:128
#define CXX_FRAME_MAGIC_VC8
Definition: cppexcept.h:26
static void * get_this_pointer(const this_ptr_offsets *off, void *object)
Definition: cppexcept.h:163
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
uint32_t entry
Definition: isohybrid.c:63
#define e
Definition: ke_i.h:82
#define debugstr_guid
Definition: kernel32.h:35
#define MSVCRT_abort
Definition: winternl.h:311
if(dx< 0)
Definition: linetemp.h:194
const GUID * guid
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
static void * get_obj_locator(void *cppobj)
Definition: cpp.c:885
#define __thiscall
Definition: cpp.c:43
void(* vtable_ptr)(void)
Definition: cpp.c:23
static unsigned int
Definition: cpp.c:62
static vtable_ptr * get_vtable(void *obj)
Definition: cpp.c:880
unsigned long MSVCRT_size_t
Definition: msvcrt.h:67
void(__cdecl * MSVCRT__se_translator_function)(unsigned int code, struct _EXCEPTION_POINTERS *info)
Definition: msvcrt.h:83
void __cdecl MSVCRT_operator_delete(void *)
Definition: heap.c:196
void(__cdecl * MSVCRT_unexpected_function)(void)
Definition: msvcrt.h:82
void(__cdecl * MSVCRT_terminate_function)(void)
Definition: msvcrt.h:80
thread_data_t * msvcrt_get_thread_data(void)
Definition: tls.c:31
char *__cdecl __unDName(char *, const char *, int, malloc_func_t, free_func_t, unsigned short int)
Definition: undname.c:1645
static void * vtable[]
Definition: typelib.c:1231
#define __ASM_GLOBAL_FUNC(name, code)
Definition: port.h:201
Definition: features.h:417
#define BOOL
Definition: nt_native.h:43
#define DEFINE_THISCALL_WRAPPER(func, args)
Definition: msvc-thiscall.c:2
static unsigned __int64 next
Definition: rand_nt.c:6
#define EH_UNWINDING
Definition: exception.h:17
const WCHAR * str
const char int int int static __inline const char * wine_dbgstr_a(const char *s)
Definition: debug.h:187
#define MSVCRT_free
Definition: msvcrt.h:152
#define MSVCRT_malloc
Definition: msvcrt.h:151
__non_rtti_object *__thiscall MSVCRT___non_rtti_object_ctor(__non_rtti_object *_this, const char *name)
Definition: cpp.c:380
void __thiscall MSVCRT_type_info_dtor(type_info *_this)
Definition: cpp.c:585
void *__thiscall MSVCRT_bad_cast_vector_dtor(bad_cast *_this, unsigned int flags)
Definition: cpp.c:517
void __thiscall MSVCRT___non_rtti_object_dtor(__non_rtti_object *_this)
Definition: cpp.c:393
const vtable_ptr MSVCRT_exception_vtable
bad_cast *__thiscall MSVCRT_bad_cast_default_ctor(bad_cast *_this)
Definition: cpp.c:487
const char *__thiscall MSVCRT_type_info_raw_name(type_info *_this)
Definition: cpp.c:629
int __thiscall MSVCRT_type_info_before(type_info *_this, const type_info *rhs)
Definition: cpp.c:574
bad_cast *__thiscall MSVCRT_bad_cast_ctor(bad_cast *_this, const char **name)
Definition: cpp.c:451
void __cdecl __ExceptionPtrRethrow(const exception_ptr *ep)
Definition: cpp.c:1808
const type_info *CDECL MSVCRT___RTtypeid(void *cppobj)
Definition: cpp.c:1314
__non_rtti_object *__thiscall MSVCRT___non_rtti_object_copy_ctor(__non_rtti_object *_this, const __non_rtti_object *rhs)
Definition: cpp.c:367
void *__thiscall MSVCRT_exception_scalar_dtor(exception *_this, unsigned int flags)
Definition: cpp.c:256
bad_typeid *__thiscall MSVCRT_bad_typeid_ctor(bad_typeid *_this, const char *name)
Definition: cpp.c:290
MSVCRT__se_translator_function CDECL MSVCRT__set_se_translator(MSVCRT__se_translator_function func)
Definition: cpp.c:1255
void *__thiscall MSVCRT_exception_vector_dtor(exception *_this, unsigned int flags)
Definition: cpp.c:233
bad_cast *__thiscall MSVCRT_bad_cast_copy_ctor(bad_cast *_this, const bad_cast *rhs)
Definition: cpp.c:463
void WINAPI _CxxThrowException(exception *object, const cxx_exception_type *type)
Definition: cpp.c:1574
void *__thiscall MSVCRT___non_rtti_object_vector_dtor(__non_rtti_object *_this, unsigned int flags)
Definition: cpp.c:415
void *CDECL MSVCRT___RTCastToVoid(void *cppobj)
Definition: cpp.c:1547
void __thiscall MSVCRT_bad_cast_dtor(bad_cast *_this)
Definition: cpp.c:496
const char *__thiscall MSVCRT_type_info_name(type_info *_this)
Definition: cpp.c:595
MSVCRT_terminate_function CDECL MSVCRT__get_terminate(void)
Definition: cpp.c:1215
exception __thiscall MSVCRT_exception_ctor_noalloc(exception *_this, char **name, int noalloc)
Definition: cpp.c:160
static void dump_obj_locator(const rtti_object_locator *ptr)
Definition: cpp.c:67
bad_cast *__thiscall MSVCRT_bad_cast_opequals(bad_cast *_this, const bad_cast *rhs)
Definition: cpp.c:506
const vtable_ptr MSVCRT_bad_cast_vtable
static void EXCEPTION_ctor(exception *_this, const char **name)
Definition: cpp.c:124
void __asm_dummy_vtables(void)
Definition: cpp.c:1000
void *__thiscall MSVCRT___non_rtti_object_scalar_dtor(__non_rtti_object *_this, unsigned int flags)
Definition: cpp.c:438
void *__thiscall MSVCRT_bad_cast_scalar_dtor(bad_cast *_this, unsigned int flags)
Definition: cpp.c:540
bad_typeid *__thiscall MSVCRT_bad_typeid_copy_ctor(bad_typeid *_this, const bad_typeid *rhs)
Definition: cpp.c:278
const char *__thiscall MSVCRT_what_exception(exception *_this)
Definition: cpp.c:268
exception __thiscall MSVCRT_exception_opequals(exception *_this, const exception *rhs)
Definition: cpp.c:217
void *__thiscall MSVCRT_type_info_vector_dtor(type_info *_this, unsigned int flags)
Definition: cpp.c:637
const vtable_ptr MSVCRT___non_rtti_object_vtable
void CDECL MSVCRT_unexpected(void)
Definition: cpp.c:1287
void CDECL MSVCRT_terminate(void)
Definition: cpp.c:1277
int __thiscall MSVCRT_type_info_opnot_equals(type_info *_this, const type_info *rhs)
Definition: cpp.c:563
__non_rtti_object *__thiscall MSVCRT___non_rtti_object_opequals(__non_rtti_object *_this, const __non_rtti_object *rhs)
Definition: cpp.c:403
exception __thiscall MSVCRT_exception_default_ctor(exception *_this)
Definition: cpp.c:193
MSVCRT_unexpected_function CDECL MSVCRT_set_unexpected(MSVCRT_unexpected_function func)
Definition: cpp.c:1233
bad_cast *__thiscall MSVCRT_bad_cast_ctor_charptr(bad_cast *_this, const char *name)
Definition: cpp.c:475
MSVCRT_unexpected_function CDECL MSVCRT__get_unexpected(void)
Definition: cpp.c:1245
void *CDECL MSVCRT___RTDynamicCast(void *cppobj, int unknown, type_info *src, type_info *dst, int do_throw)
Definition: cpp.c:1403
exception __thiscall MSVCRT_exception_copy_ctor(exception *_this, const exception *rhs)
Definition: cpp.c:173
void __thiscall MSVCRT_bad_typeid_dtor(bad_typeid *_this)
Definition: cpp.c:311
const vtable_ptr MSVCRT_bad_typeid_vtable
exception __thiscall MSVCRT_exception_ctor(exception *_this, const char **name)
Definition: cpp.c:149
bad_typeid *__thiscall MSVCRT_bad_typeid_default_ctor(bad_typeid *_this)
Definition: cpp.c:302
void *__thiscall MSVCRT_bad_typeid_scalar_dtor(bad_typeid *_this, unsigned int flags)
Definition: cpp.c:355
void *__thiscall MSVCRT_bad_typeid_vector_dtor(bad_typeid *_this, unsigned int flags)
Definition: cpp.c:332
const vtable_ptr MSVCRT_type_info_vtable
void __thiscall MSVCRT_exception_dtor(exception *_this)
Definition: cpp.c:206
int __thiscall MSVCRT_type_info_opequals_equals(type_info *_this, const type_info *rhs)
Definition: cpp.c:552
bad_typeid *__thiscall MSVCRT_bad_typeid_opequals(bad_typeid *_this, const bad_typeid *rhs)
Definition: cpp.c:321
unsigned char MSVCRT_bool
Definition: msvcrt.h:68
int __cdecl MSVCRT_strcmp(const char *, const char *)
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
DWORD ExceptionCode
Definition: compat.h:208
DWORD NumberParameters
Definition: compat.h:212
DWORD ExceptionFlags
Definition: compat.h:209
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
const cxx_type_info_table * type_info_table
Definition: cppexcept.h:148
const cxx_type_info * info[3]
Definition: cppexcept.h:134
cxx_copy_ctor copy_ctor
Definition: cppexcept.h:125
const type_info * type_info
Definition: cppexcept.h:122
this_ptr_offsets offsets
Definition: cppexcept.h:123
unsigned int size
Definition: cppexcept.h:124
char * name
Definition: cpp.c:28
vtable_ptr * vtable
Definition: cpp.c:27
int do_free
Definition: cpp.c:29
struct __type_info_node * next
Definition: cpp.c:41
void * memPtr
Definition: cpp.c:40
char mangled[16]
Definition: cpp.c:36
const rtti_base_descriptor * bases[10]
Definition: cxx.h:188
this_ptr_offsets offsets
Definition: cxx.h:182
int num_base_classes
Definition: cxx.h:181
const type_info * type_descriptor
Definition: cxx.h:180
unsigned int attributes
Definition: cxx.h:183
const rtti_base_array * base_classes
Definition: cxx.h:196
const type_info * type_descriptor
Definition: cxx.h:204
unsigned int signature
Definition: cxx.h:201
int base_class_offset
Definition: cxx.h:202
const rtti_object_hierarchy * type_hierarchy
Definition: cxx.h:205
Definition: match.c:390
EXCEPTION_RECORD * rec
Definition: cpp.c:1708
int * ref
Definition: cpp.c:1709
Definition: _hash_fun.h:40
Definition: name.c:39
#define EH_NONCONTINUABLE
Definition: stubs.h:9
#define SLIST_ENTRY(type)
Definition: queue.h:102
int32_t INT_PTR
Definition: typedefs.h:64
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint32_t ULONG_PTR
Definition: typedefs.h:65
Definition: dlist.c:348
int ret
#define WINAPI
Definition: msvc.h:6
#define InterlockedPushEntrySList(SListHead, SListEntry)
Definition: rtlfuncs.h:3389
#define InterlockedFlushSList(SListHead)
Definition: rtlfuncs.h:3395
#define const
Definition: zconf.h:233