ReactOS 0.4.15-dev-8119-g4fb2fdb
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 __GNUC__
1000#endif
1001
1007#if _MSVCR_VER >= 80
1008__ASM_VTABLE(exception_old,
1011__ASM_VTABLE(bad_alloc,
1014#endif
1015__ASM_VTABLE(bad_typeid,
1018__ASM_VTABLE(bad_cast,
1021__ASM_VTABLE(__non_rtti_object,
1024#if _MSVCR_VER >= 100
1025__ASM_VTABLE(scheduler_resource_allocation_error,
1028__ASM_VTABLE(improper_lock,
1031__ASM_VTABLE(invalid_scheduler_policy_key,
1034__ASM_VTABLE(invalid_scheduler_policy_value,
1037__ASM_VTABLE(invalid_scheduler_policy_thread_specification,
1040__ASM_VTABLE(improper_scheduler_attach,
1043__ASM_VTABLE(improper_scheduler_detach,
1046#endif
1047
1048#ifndef __GNUC__
1049}
1050#endif
1051
1052DEFINE_RTTI_DATA0( type_info, 0, ".?AVtype_info@@" )
1053#if _MSVCR_VER >= 80
1054DEFINE_RTTI_DATA0( exception, 0, ".?AVexception@std@@" )
1055DEFINE_RTTI_DATA0( exception_old, 0, ".?AVexception@@" )
1056DEFINE_RTTI_DATA1( bad_typeid, 0, &exception_rtti_base_descriptor, ".?AVbad_typeid@std@@" )
1057DEFINE_RTTI_DATA1( bad_cast, 0, &exception_rtti_base_descriptor, ".?AVbad_cast@std@@" )
1058DEFINE_RTTI_DATA2( __non_rtti_object, 0, &bad_typeid_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AV__non_rtti_object@std@@" )
1059DEFINE_RTTI_DATA1( bad_alloc, 0, &exception_rtti_base_descriptor, ".?AVbad_alloc@std@@" )
1060#else
1061DEFINE_RTTI_DATA0( exception, 0, ".?AVexception@@" )
1062DEFINE_RTTI_DATA1( bad_typeid, 0, &exception_rtti_base_descriptor, ".?AVbad_typeid@@" )
1063DEFINE_RTTI_DATA1( bad_cast, 0, &exception_rtti_base_descriptor, ".?AVbad_cast@@" )
1064DEFINE_RTTI_DATA2( __non_rtti_object, 0, &bad_typeid_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AV__non_rtti_object@@" )
1065#endif
1066#if _MSVCR_VER >= 100
1067DEFINE_RTTI_DATA1(scheduler_resource_allocation_error, 0, &exception_rtti_base_descriptor,
1068 ".?AVscheduler_resource_allocation_error@Concurrency@@")
1069DEFINE_RTTI_DATA1(improper_lock, 0, &exception_rtti_base_descriptor, ".?AVimproper_lock@Concurrency@@" )
1070DEFINE_RTTI_DATA1(invalid_scheduler_policy_key, 0, &exception_rtti_base_descriptor,
1071 ".?AVinvalid_scheduler_policy_key@Concurrency@@" )
1072DEFINE_RTTI_DATA1(invalid_scheduler_policy_value, 0, &exception_rtti_base_descriptor,
1073 ".?AVinvalid_scheduler_policy_value@Concurrency@@" )
1074DEFINE_RTTI_DATA1(invalid_scheduler_policy_thread_specification, 0, &exception_rtti_base_descriptor,
1075 ".?AVinvalid_scheduler_policy_thread_specification@Concurrency@@" )
1076DEFINE_RTTI_DATA1(improper_scheduler_attach, 0, &exception_rtti_base_descriptor,
1077 ".?AVimproper_scheduler_attach@Concurrency@@" )
1078DEFINE_RTTI_DATA1(improper_scheduler_detach, 0, &exception_rtti_base_descriptor,
1079 ".?AVimproper_scheduler_detach@Concurrency@@" )
1080#endif
1081
1082DEFINE_EXCEPTION_TYPE_INFO( exception, 0, NULL, NULL )
1083DEFINE_EXCEPTION_TYPE_INFO( bad_typeid, 1, &exception_cxx_type_info, NULL )
1084DEFINE_EXCEPTION_TYPE_INFO( bad_cast, 1, &exception_cxx_type_info, NULL )
1085DEFINE_EXCEPTION_TYPE_INFO( __non_rtti_object, 2, &bad_typeid_cxx_type_info, &exception_cxx_type_info )
1086#if _MSVCR_VER >= 80
1087DEFINE_EXCEPTION_TYPE_INFO( bad_alloc, 1, &exception_cxx_type_info, NULL )
1088#endif
1089#if _MSVCR_VER >= 100
1090DEFINE_EXCEPTION_TYPE_INFO(scheduler_resource_allocation_error, 1, &exception_cxx_type_info, NULL)
1091DEFINE_EXCEPTION_TYPE_INFO(improper_lock, 1, &exception_cxx_type_info, NULL)
1092DEFINE_EXCEPTION_TYPE_INFO(invalid_scheduler_policy_key, 1, &exception_cxx_type_info, NULL)
1093DEFINE_EXCEPTION_TYPE_INFO(invalid_scheduler_policy_value, 1, &exception_cxx_type_info, NULL)
1094DEFINE_EXCEPTION_TYPE_INFO(invalid_scheduler_policy_thread_specification, 1, &exception_cxx_type_info, NULL)
1095DEFINE_EXCEPTION_TYPE_INFO(improper_scheduler_attach, 1, &exception_cxx_type_info, NULL)
1096DEFINE_EXCEPTION_TYPE_INFO(improper_scheduler_detach, 1, &exception_cxx_type_info, NULL)
1097#endif
1098
1099void msvcrt_init_exception(void *base)
1100{
1101#ifdef __x86_64__
1102 init_type_info_rtti(base);
1103 init_exception_rtti(base);
1104#if _MSVCR_VER >= 80
1105 init_exception_old_rtti(base);
1106 init_bad_alloc_rtti(base);
1107#endif
1108 init_bad_typeid_rtti(base);
1109 init_bad_cast_rtti(base);
1110 init___non_rtti_object_rtti(base);
1111#if _MSVCR_VER >= 100
1112 init_scheduler_resource_allocation_error_rtti(base);
1113 init_improper_lock_rtti(base);
1114 init_invalid_scheduler_policy_key_rtti(base);
1115 init_invalid_scheduler_policy_value_rtti(base);
1116 init_invalid_scheduler_policy_thread_specification_rtti(base);
1117 init_improper_scheduler_attach_rtti(base);
1118 init_improper_scheduler_detach_rtti(base);
1119#endif
1120
1121 init_exception_cxx(base);
1122 init_bad_typeid_cxx(base);
1123 init_bad_cast_cxx(base);
1124 init___non_rtti_object_cxx(base);
1125#if _MSVCR_VER >= 80
1126 init_bad_alloc_cxx(base);
1127#endif
1128#if _MSVCR_VER >= 100
1129 init_scheduler_resource_allocation_error_cxx(base);
1130 init_improper_lock_cxx(base);
1131 init_invalid_scheduler_policy_key_cxx(base);
1132 init_invalid_scheduler_policy_value_cxx(base);
1133 init_invalid_scheduler_policy_thread_specification_cxx(base);
1134 init_improper_scheduler_attach_cxx(base);
1135 init_improper_scheduler_detach_cxx(base);
1136#endif
1137#endif
1138}
1139
1140#if _MSVCR_VER >= 80
1141void throw_exception(exception_type et, HRESULT hr, const char *str)
1142{
1143 switch(et) {
1144 case EXCEPTION_BAD_ALLOC: {
1145 bad_alloc e;
1146 bad_alloc_ctor(&e, &str);
1147 _CxxThrowException(&e, &bad_alloc_exception_type);
1148 }
1149#if _MSVCR_VER >= 100
1150 case EXCEPTION_SCHEDULER_RESOURCE_ALLOCATION_ERROR: {
1151 scheduler_resource_allocation_error e;
1152 scheduler_resource_allocation_error_ctor_name(&e, str, hr);
1153 _CxxThrowException(&e.e, &scheduler_resource_allocation_error_exception_type);
1154 }
1155 case EXCEPTION_IMPROPER_LOCK: {
1156 improper_lock e;
1157 improper_lock_ctor_str(&e, str);
1158 _CxxThrowException(&e, &improper_lock_exception_type);
1159 }
1160 case EXCEPTION_INVALID_SCHEDULER_POLICY_KEY: {
1161 invalid_scheduler_policy_key e;
1162 invalid_scheduler_policy_key_ctor_str(&e, str);
1163 _CxxThrowException(&e, &invalid_scheduler_policy_key_exception_type);
1164 }
1165 case EXCEPTION_INVALID_SCHEDULER_POLICY_VALUE: {
1166 invalid_scheduler_policy_value e;
1167 invalid_scheduler_policy_value_ctor_str(&e, str);
1168 _CxxThrowException(&e, &invalid_scheduler_policy_value_exception_type);
1169 }
1170 case EXCEPTION_INVALID_SCHEDULER_POLICY_THREAD_SPECIFICATION: {
1171 invalid_scheduler_policy_thread_specification e;
1172 invalid_scheduler_policy_thread_specification_ctor_str(&e, str);
1173 _CxxThrowException(&e, &invalid_scheduler_policy_thread_specification_exception_type);
1174 }
1175 case EXCEPTION_IMPROPER_SCHEDULER_ATTACH: {
1176 improper_scheduler_attach e;
1177 improper_scheduler_attach_ctor_str(&e, str);
1178 _CxxThrowException(&e, &improper_scheduler_attach_exception_type);
1179 }
1180 case EXCEPTION_IMPROPER_SCHEDULER_DETACH: {
1181 improper_scheduler_detach e;
1182 improper_scheduler_detach_ctor_str(&e, str);
1183 _CxxThrowException(&e, &improper_scheduler_detach_exception_type);
1184 }
1185#endif
1186 }
1187}
1188#endif
1189
1190/******************************************************************
1191 * ?set_terminate@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
1192 *
1193 * Install a handler to be called when terminate() is called.
1194 *
1195 * PARAMS
1196 * func [I] Handler function to install
1197 *
1198 * RETURNS
1199 * The previously installed handler function, if any.
1200 */
1201MSVCRT_terminate_function CDECL MSVCRT_set_terminate(MSVCRT_terminate_function func)
1202{
1203 thread_data_t *data = msvcrt_get_thread_data();
1204 MSVCRT_terminate_function previous = data->terminate_handler;
1205 TRACE("(%p) returning %p\n",func,previous);
1207 return previous;
1208}
1209
1210/******************************************************************
1211 * _get_terminate (MSVCRT.@)
1212 */
1214{
1216 TRACE("returning %p\n", data->terminate_handler);
1217 return data->terminate_handler;
1218}
1219
1220/******************************************************************
1221 * ?set_unexpected@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
1222 *
1223 * Install a handler to be called when unexpected() is called.
1224 *
1225 * PARAMS
1226 * func [I] Handler function to install
1227 *
1228 * RETURNS
1229 * The previously installed handler function, if any.
1230 */
1232{
1234 MSVCRT_unexpected_function previous = data->unexpected_handler;
1235 TRACE("(%p) returning %p\n",func,previous);
1236 data->unexpected_handler = func;
1237 return previous;
1238}
1239
1240/******************************************************************
1241 * _get_unexpected (MSVCRT.@)
1242 */
1244{
1246 TRACE("returning %p\n", data->unexpected_handler);
1247 return data->unexpected_handler;
1248}
1249
1250/******************************************************************
1251 * ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z (MSVCRT.@)
1252 */
1254{
1256 MSVCRT__se_translator_function previous = data->se_translator;
1257 TRACE("(%p) returning %p\n",func,previous);
1258 data->se_translator = func;
1259 return previous;
1260}
1261
1262/******************************************************************
1263 * ?terminate@@YAXXZ (MSVCRT.@)
1264 *
1265 * Default handler for an unhandled exception.
1266 *
1267 * PARAMS
1268 * None.
1269 *
1270 * RETURNS
1271 * This function does not return. Either control resumes from any
1272 * handler installed by calling set_terminate(), or (by default) abort()
1273 * is called.
1274 */
1276{
1278 if (data->terminate_handler) data->terminate_handler();
1279 MSVCRT_abort();
1280}
1281
1282/******************************************************************
1283 * ?unexpected@@YAXXZ (MSVCRT.@)
1284 */
1286{
1288 if (data->unexpected_handler) data->unexpected_handler();
1290}
1291
1292
1293/******************************************************************
1294 * __RTtypeid (MSVCRT.@)
1295 *
1296 * Retrieve the Run Time Type Information (RTTI) for a C++ object.
1297 *
1298 * PARAMS
1299 * cppobj [I] C++ object to get type information for.
1300 *
1301 * RETURNS
1302 * Success: A type_info object describing cppobj.
1303 * Failure: If the object to be cast has no RTTI, a __non_rtti_object
1304 * exception is thrown. If cppobj is NULL, a bad_typeid exception
1305 * is thrown. In either case, this function does not return.
1306 *
1307 * NOTES
1308 * This function is usually called by compiler generated code as a result
1309 * of using one of the C++ dynamic cast statements.
1310 */
1311#ifndef __x86_64__
1313{
1314 const type_info *ret;
1315
1316 if (!cppobj)
1317 {
1318 bad_typeid e;
1319 MSVCRT_bad_typeid_ctor( &e, "Attempted a typeid of NULL pointer!" );
1320 _CxxThrowException( &e, &bad_typeid_exception_type );
1321 return NULL;
1322 }
1323
1324 __TRY
1325 {
1326 const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
1327 ret = obj_locator->type_descriptor;
1328 }
1330 {
1331 __non_rtti_object e;
1332 MSVCRT___non_rtti_object_ctor( &e, "Bad read pointer - no RTTI data!" );
1333 _CxxThrowException( &e, &__non_rtti_object_exception_type );
1334 return NULL;
1335 }
1336 __ENDTRY
1337 return ret;
1338}
1339
1340#else
1341
1342const type_info* CDECL MSVCRT___RTtypeid(void *cppobj)
1343{
1344 const type_info *ret;
1345
1346 if (!cppobj)
1347 {
1348 bad_typeid e;
1349 MSVCRT_bad_typeid_ctor( &e, "Attempted a typeid of NULL pointer!" );
1350 _CxxThrowException( &e, &bad_typeid_exception_type );
1351 return NULL;
1352 }
1353
1354 __TRY
1355 {
1356 const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
1357 char *base;
1358
1359 if(obj_locator->signature == 0)
1360 base = RtlPcToFileHeader((void*)obj_locator, (void**)&base);
1361 else
1362 base = (char*)obj_locator - obj_locator->object_locator;
1363
1364 ret = (type_info*)(base + obj_locator->type_descriptor);
1365 }
1367 {
1368 __non_rtti_object e;
1369 MSVCRT___non_rtti_object_ctor( &e, "Bad read pointer - no RTTI data!" );
1370 _CxxThrowException( &e, &__non_rtti_object_exception_type );
1371 return NULL;
1372 }
1373 __ENDTRY
1374 return ret;
1375}
1376#endif
1377
1378/******************************************************************
1379 * __RTDynamicCast (MSVCRT.@)
1380 *
1381 * Dynamically cast a C++ object to one of its base classes.
1382 *
1383 * PARAMS
1384 * cppobj [I] Any C++ object to cast
1385 * unknown [I] Reserved, set to 0
1386 * src [I] type_info object describing cppobj
1387 * dst [I] type_info object describing the base class to cast to
1388 * do_throw [I] TRUE = throw an exception if the cast fails, FALSE = don't
1389 *
1390 * RETURNS
1391 * Success: The address of cppobj, cast to the object described by dst.
1392 * Failure: NULL, If the object to be cast has no RTTI, or dst is not a
1393 * valid cast for cppobj. If do_throw is TRUE, a bad_cast exception
1394 * is thrown and this function does not return.
1395 *
1396 * NOTES
1397 * This function is usually called by compiler generated code as a result
1398 * of using one of the C++ dynamic cast statements.
1399 */
1400#ifndef __x86_64__
1401void* CDECL MSVCRT___RTDynamicCast(void *cppobj, int unknown,
1403 int do_throw)
1404{
1405 void *ret;
1406
1407 if (!cppobj) return NULL;
1408
1409 TRACE("obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)\n",
1410 cppobj, unknown, src, dbgstr_type_info(src), dst, dbgstr_type_info(dst), do_throw);
1411
1412 /* To cast an object at runtime:
1413 * 1.Find out the true type of the object from the typeinfo at vtable[-1]
1414 * 2.Search for the destination type in the class hierarchy
1415 * 3.If destination type is found, return base object address + dest offset
1416 * Otherwise, fail the cast
1417 *
1418 * FIXME: the unknown parameter doesn't seem to be used for anything
1419 */
1420 __TRY
1421 {
1422 int i;
1423 const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
1424 const rtti_object_hierarchy *obj_bases = obj_locator->type_hierarchy;
1425 const rtti_base_descriptor * const* base_desc = obj_bases->base_classes->bases;
1426
1427 if (TRACE_ON(msvcrt)) dump_obj_locator(obj_locator);
1428
1429 ret = NULL;
1430 for (i = 0; i < obj_bases->array_len; i++)
1431 {
1432 const type_info *typ = base_desc[i]->type_descriptor;
1433
1434 if (!strcmp(typ->mangled, dst->mangled))
1435 {
1436 /* compute the correct this pointer for that base class */
1437 void *this_ptr = (char *)cppobj - obj_locator->base_class_offset;
1438 ret = get_this_pointer( &base_desc[i]->offsets, this_ptr );
1439 break;
1440 }
1441 }
1442 /* VC++ sets do_throw to 1 when the result of a dynamic_cast is assigned
1443 * to a reference, since references cannot be NULL.
1444 */
1445 if (!ret && do_throw)
1446 {
1447 const char *msg = "Bad dynamic_cast!";
1448 bad_cast e;
1450 _CxxThrowException( &e, &bad_cast_exception_type );
1451 }
1452 }
1454 {
1455 __non_rtti_object e;
1456 MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" );
1457 _CxxThrowException( &e, &__non_rtti_object_exception_type );
1458 return NULL;
1459 }
1460 __ENDTRY
1461 return ret;
1462}
1463
1464#else
1465
1466void* CDECL MSVCRT___RTDynamicCast(void *cppobj, int unknown,
1468 int do_throw)
1469{
1470 void *ret;
1471
1472 if (!cppobj) return NULL;
1473
1474 TRACE("obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)\n",
1475 cppobj, unknown, src, dbgstr_type_info(src), dst, dbgstr_type_info(dst), do_throw);
1476
1477 __TRY
1478 {
1479 int i;
1480 const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
1481 const rtti_object_hierarchy *obj_bases;
1482 const rtti_base_array *base_array;
1483 char *base;
1484
1485 if (TRACE_ON(msvcrt)) dump_obj_locator(obj_locator);
1486
1487 if(obj_locator->signature == 0)
1488 base = RtlPcToFileHeader((void*)obj_locator, (void**)&base);
1489 else
1490 base = (char*)obj_locator - obj_locator->object_locator;
1491
1492 obj_bases = (const rtti_object_hierarchy*)(base + obj_locator->type_hierarchy);
1493 base_array = (const rtti_base_array*)(base + obj_bases->base_classes);
1494
1495 ret = NULL;
1496 for (i = 0; i < obj_bases->array_len; i++)
1497 {
1498 const rtti_base_descriptor *base_desc = (const rtti_base_descriptor*)(base + base_array->bases[i]);
1499 const type_info *typ = (const type_info*)(base + base_desc->type_descriptor);
1500
1501 if (!strcmp(typ->mangled, dst->mangled))
1502 {
1503 void *this_ptr = (char *)cppobj - obj_locator->base_class_offset;
1504 ret = get_this_pointer( &base_desc->offsets, this_ptr );
1505 break;
1506 }
1507 }
1508 if (!ret && do_throw)
1509 {
1510 const char *msg = "Bad dynamic_cast!";
1511 bad_cast e;
1513 _CxxThrowException( &e, &bad_cast_exception_type );
1514 }
1515 }
1517 {
1518 __non_rtti_object e;
1519 MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" );
1520 _CxxThrowException( &e, &__non_rtti_object_exception_type );
1521 return NULL;
1522 }
1523 __ENDTRY
1524 return ret;
1525}
1526#endif
1527
1528
1529/******************************************************************
1530 * __RTCastToVoid (MSVCRT.@)
1531 *
1532 * Dynamically cast a C++ object to a void*.
1533 *
1534 * PARAMS
1535 * cppobj [I] The C++ object to cast
1536 *
1537 * RETURNS
1538 * Success: The base address of the object as a void*.
1539 * Failure: NULL, if cppobj is NULL or has no RTTI.
1540 *
1541 * NOTES
1542 * This function is usually called by compiler generated code as a result
1543 * of using one of the C++ dynamic cast statements.
1544 */
1545void* CDECL MSVCRT___RTCastToVoid(void *cppobj)
1546{
1547 void *ret;
1548
1549 if (!cppobj) return NULL;
1550
1551 __TRY
1552 {
1553 const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
1554 ret = (char *)cppobj - obj_locator->base_class_offset;
1555 }
1557 {
1558 __non_rtti_object e;
1559 MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" );
1560 _CxxThrowException( &e, &__non_rtti_object_exception_type );
1561 return NULL;
1562 }
1563 __ENDTRY
1564 return ret;
1565}
1566
1567
1568/*********************************************************************
1569 * _CxxThrowException (MSVCRT.@)
1570 */
1571#ifndef __x86_64__
1573{
1574 ULONG_PTR args[3];
1575
1577 args[1] = (ULONG_PTR)object;
1578 args[2] = (ULONG_PTR)type;
1580}
1581#else
1583{
1584 ULONG_PTR args[4];
1585
1587 args[1] = (ULONG_PTR)object;
1588 args[2] = (ULONG_PTR)type;
1589 RtlPcToFileHeader( (void*)type, (void**)&args[3]);
1591}
1592#endif
1593
1594#if _MSVCR_VER >= 80
1595
1596/*********************************************************************
1597 * ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z
1598 * ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z
1599 */
1600#ifndef __x86_64__
1602{
1603 int ret = -1;
1604
1605 TRACE("(%p %p)\n", ti, ep);
1606
1607 __TRY
1608 {
1610
1611 if (rec->ExceptionCode==CXX_EXCEPTION && rec->NumberParameters==3 &&
1615 {
1616 const cxx_type_info_table *tit = ((cxx_exception_type*)rec->ExceptionInformation[2])->type_info_table;
1617 int i;
1618
1619 for (i=0; i<tit->count; i++) {
1620 if (ti==tit->info[i]->type_info || !strcmp(ti->mangled, tit->info[i]->type_info->mangled))
1621 {
1622 ret = 1;
1623 break;
1624 }
1625 }
1626
1627 if (i == tit->count)
1628 ret = 0;
1629 }
1630 }
1632 __ENDTRY
1633
1634 if(ret == -1)
1636 return ret;
1637}
1638#else
1640{
1641 int ret = -1;
1642
1643 TRACE("(%p %p)\n", ti, ep);
1644
1645 __TRY
1646 {
1648
1649 if (rec->ExceptionCode==CXX_EXCEPTION && rec->NumberParameters==4 &&
1653 {
1656 int i;
1657
1658 for (i=0; i<tit->count; i++) {
1659 const cxx_type_info *cti = (const cxx_type_info*)(rec->ExceptionInformation[3]+tit->info[i]);
1660 const type_info *except_ti = (const type_info*)(rec->ExceptionInformation[3]+cti->type_info);
1661 if (ti==except_ti || !strcmp(ti->mangled, except_ti->mangled))
1662 {
1663 ret = 1;
1664 break;
1665 }
1666 }
1667
1668 if (i == tit->count)
1669 ret = 0;
1670 }
1671 }
1673 __ENDTRY
1674
1675 if(ret == -1)
1677 return ret;
1678}
1679#endif
1680
1681/*********************************************************************
1682 * __clean_type_info_names_internal (MSVCR80.@)
1683 */
1684void CDECL __clean_type_info_names_internal(void *p)
1685{
1686 FIXME("(%p) stub\n", p);
1687}
1688
1689/*********************************************************************
1690 * ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z (MSVCR100.@)
1691 */
1692DEFINE_THISCALL_WRAPPER(type_info_name_internal_method,8)
1693const char * __thiscall type_info_name_internal_method(type_info * _this, struct __type_info_node *node)
1694{
1695 static int once;
1696 if (node && !once++) FIXME("type_info_node parameter ignored\n");
1697
1698 return MSVCRT_type_info_name(_this);
1699}
1700
1701#endif /* _MSVCR_VER >= 80 */
1702
1703/* std::exception_ptr class helpers */
1704typedef struct
1705{
1707 int *ref; /* not binary compatible with native msvcr100 */
1709
1710#if _MSVCR_VER >= 100
1711
1712/*********************************************************************
1713 * ?__ExceptionPtrCreate@@YAXPAX@Z
1714 * ?__ExceptionPtrCreate@@YAXPEAX@Z
1715 */
1716void __cdecl __ExceptionPtrCreate(exception_ptr *ep)
1717{
1718 TRACE("(%p)\n", ep);
1719
1720 ep->rec = NULL;
1721 ep->ref = NULL;
1722}
1723
1724#if defined(__i386__) && !defined(__MINGW32__)
1725extern void call_dtor(const cxx_exception_type *type, void *func, void *object);
1726
1727__ASM_GLOBAL_FUNC( call_dtor,
1728 "movl 12(%esp),%ecx\n\t"
1729 "call *8(%esp)\n\t"
1730 "ret" );
1731#elif __x86_64__
1732static inline void call_dtor(const cxx_exception_type *type, unsigned int dtor, void *object)
1733{
1734 char *base = RtlPcToFileHeader((void*)type, (void**)&base);
1735 void (__cdecl *func)(void*) = (void*)(base + dtor);
1736 func(object);
1737}
1738#else
1739#define call_dtor(type, func, object) ((void (__thiscall*)(void*))(func))(object)
1740#endif
1741
1742/*********************************************************************
1743 * ?__ExceptionPtrDestroy@@YAXPAX@Z
1744 * ?__ExceptionPtrDestroy@@YAXPEAX@Z
1745 */
1746void __cdecl __ExceptionPtrDestroy(exception_ptr *ep)
1747{
1748 TRACE("(%p)\n", ep);
1749
1750 if (!ep->rec)
1751 return;
1752
1753 if (!InterlockedDecrement(ep->ref))
1754 {
1755 if (ep->rec->ExceptionCode == CXX_EXCEPTION)
1756 {
1757 const cxx_exception_type *type = (void*)ep->rec->ExceptionInformation[2];
1758 void *obj = (void*)ep->rec->ExceptionInformation[1];
1759
1760 if (type && type->destructor) call_dtor(type, type->destructor, obj);
1762 }
1763
1764 HeapFree(GetProcessHeap(), 0, ep->rec);
1765 HeapFree(GetProcessHeap(), 0, ep->ref);
1766 }
1767}
1768
1769/*********************************************************************
1770 * ?__ExceptionPtrCopy@@YAXPAXPBX@Z
1771 * ?__ExceptionPtrCopy@@YAXPEAXPEBX@Z
1772 */
1773void __cdecl __ExceptionPtrCopy(exception_ptr *ep, const exception_ptr *copy)
1774{
1775 TRACE("(%p %p)\n", ep, copy);
1776
1777 /* don't destroy object stored in ep */
1778 *ep = *copy;
1779 if (ep->ref)
1781}
1782
1783/*********************************************************************
1784 * ?__ExceptionPtrAssign@@YAXPAXPBX@Z
1785 * ?__ExceptionPtrAssign@@YAXPEAXPEBX@Z
1786 */
1787void __cdecl __ExceptionPtrAssign(exception_ptr *ep, const exception_ptr *assign)
1788{
1789 TRACE("(%p %p)\n", ep, assign);
1790
1791 /* don't destroy object stored in ep */
1792 if (ep->ref)
1794
1795 *ep = *assign;
1796 if (ep->ref)
1798}
1799
1800#endif /* _MSVCR_VER >= 100 */
1801
1802/*********************************************************************
1803 * ?__ExceptionPtrRethrow@@YAXPBX@Z
1804 * ?__ExceptionPtrRethrow@@YAXPEBX@Z
1805 */
1807{
1808 TRACE("(%p)\n", ep);
1809
1810 if (!ep->rec)
1811 {
1812 static const char *exception_msg = "bad exception";
1813 exception e;
1814
1815 MSVCRT_exception_ctor(&e, &exception_msg);
1816 _CxxThrowException(&e, &exception_exception_type);
1817 return;
1818 }
1819
1822}
1823
1824#if _MSVCR_VER >= 100
1825
1826#ifdef __i386__
1827extern void call_copy_ctor( void *func, void *this, void *src, int has_vbase );
1828#else
1829static inline void call_copy_ctor( void *func, void *this, void *src, int has_vbase )
1830{
1831 TRACE( "calling copy ctor %p object %p src %p\n", func, this, src );
1832 if (has_vbase)
1833 ((void (__cdecl*)(void*, void*, BOOL))func)(this, src, 1);
1834 else
1835 ((void (__cdecl*)(void*, void*))func)(this, src);
1836}
1837#endif
1838
1839/*********************************************************************
1840 * ?__ExceptionPtrCurrentException@@YAXPAX@Z
1841 * ?__ExceptionPtrCurrentException@@YAXPEAX@Z
1842 */
1843#ifndef __x86_64__
1844void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep)
1845{
1846 EXCEPTION_RECORD *rec = msvcrt_get_thread_data()->exc_record;
1847
1848 TRACE("(%p)\n", ep);
1849
1850 if (!rec)
1851 {
1852 ep->rec = NULL;
1853 ep->ref = NULL;
1854 return;
1855 }
1856
1857 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1858 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1859
1860 *ep->rec = *rec;
1861 *ep->ref = 1;
1862
1863 if (ep->rec->ExceptionCode == CXX_EXCEPTION)
1864 {
1865 const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2];
1866 const cxx_type_info *ti;
1867 void **data, *obj;
1868
1869 ti = et->type_info_table->info[0];
1870 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1871
1872 obj = (void*)ep->rec->ExceptionInformation[1];
1873 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1874 {
1875 memcpy(data, obj, ti->size);
1876 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1877 }
1878 else if (ti->copy_ctor)
1879 {
1880 call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj),
1881 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS);
1882 }
1883 else
1884 memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size);
1886 }
1887 return;
1888}
1889#else
1890void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep)
1891{
1892 EXCEPTION_RECORD *rec = msvcrt_get_thread_data()->exc_record;
1893
1894 TRACE("(%p)\n", ep);
1895
1896 if (!rec)
1897 {
1898 ep->rec = NULL;
1899 ep->ref = NULL;
1900 return;
1901 }
1902
1903 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1904 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1905
1906 *ep->rec = *rec;
1907 *ep->ref = 1;
1908
1909 if (ep->rec->ExceptionCode == CXX_EXCEPTION)
1910 {
1911 const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2];
1912 const cxx_type_info *ti;
1913 void **data, *obj;
1914 char *base = RtlPcToFileHeader((void*)et, (void**)&base);
1915
1916 ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + et->type_info_table))->info[0]);
1917 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1918
1919 obj = (void*)ep->rec->ExceptionInformation[1];
1920 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1921 {
1922 memcpy(data, obj, ti->size);
1923 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1924 }
1925 else if (ti->copy_ctor)
1926 {
1927 call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj),
1928 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS);
1929 }
1930 else
1931 memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size);
1933 }
1934 return;
1935}
1936#endif
1937
1938#endif /* _MSVCR_VER >= 100 */
1939
1940#if _MSVCR_VER >= 110
1941/*********************************************************************
1942 * ?__ExceptionPtrToBool@@YA_NPBX@Z
1943 * ?__ExceptionPtrToBool@@YA_NPEBX@Z
1944 */
1945MSVCRT_bool __cdecl __ExceptionPtrToBool(exception_ptr *ep)
1946{
1947 return !!ep->rec;
1948}
1949#endif
1950
1951#if _MSVCR_VER >= 100
1952
1953/*********************************************************************
1954 * ?__ExceptionPtrCopyException@@YAXPAXPBX1@Z
1955 * ?__ExceptionPtrCopyException@@YAXPEAXPEBX1@Z
1956 */
1957#ifndef __x86_64__
1958void __cdecl __ExceptionPtrCopyException(exception_ptr *ep,
1959 exception *object, const cxx_exception_type *type)
1960{
1961 const cxx_type_info *ti;
1962 void **data;
1963
1964 __ExceptionPtrDestroy(ep);
1965
1966 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
1967 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1968 *ep->ref = 1;
1969
1970 memset(ep->rec, 0, sizeof(EXCEPTION_RECORD));
1973 ep->rec->NumberParameters = 3;
1976
1977 ti = type->type_info_table->info[0];
1978 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
1979 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
1980 {
1981 memcpy(data, object, ti->size);
1982 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
1983 }
1984 else if (ti->copy_ctor)
1985 {
1986 call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, object),
1988 }
1989 else
1990 memcpy(data, get_this_pointer(&ti->offsets, object), ti->size);
1992}
1993#else
1994void __cdecl __ExceptionPtrCopyException(exception_ptr *ep,
1995 exception *object, const cxx_exception_type *type)
1996{
1997 const cxx_type_info *ti;
1998 void **data;
1999 char *base;
2000
2001 RtlPcToFileHeader((void*)type, (void**)&base);
2002 __ExceptionPtrDestroy(ep);
2003
2004 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
2005 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
2006 *ep->ref = 1;
2007
2008 memset(ep->rec, 0, sizeof(EXCEPTION_RECORD));
2011 ep->rec->NumberParameters = 4;
2015
2016 ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + type->type_info_table))->info[0]);
2017 data = HeapAlloc(GetProcessHeap(), 0, ti->size);
2018 if (ti->flags & CLASS_IS_SIMPLE_TYPE)
2019 {
2020 memcpy(data, object, ti->size);
2021 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
2022 }
2023 else if (ti->copy_ctor)
2024 {
2025 call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, object),
2027 }
2028 else
2029 memcpy(data, get_this_pointer(&ti->offsets, object), ti->size);
2031}
2032#endif
2033
2034MSVCRT_bool __cdecl __ExceptionPtrCompare(const exception_ptr *ep1, const exception_ptr *ep2)
2035{
2036 return ep1->rec == ep2->rec;
2037}
2038
2039#endif /* _MSVCR_VER >= 100 */
2040
2041#if _MSVCR_VER >= 80
2042void* __cdecl __AdjustPointer(void *obj, const this_ptr_offsets *off)
2043{
2044 return get_this_pointer(off, obj);
2045}
2046#endif
2047
2048#if _MSVCR_VER >= 140
2049
2050typedef struct
2051{
2052 char *name;
2053 char mangled[1];
2054} type_info140;
2055
2056typedef struct
2057{
2059 char name[1];
2060} type_info_entry;
2061
2062static void* CDECL type_info_entry_malloc(MSVCRT_size_t size)
2063{
2064 type_info_entry *ret = MSVCRT_malloc(FIELD_OFFSET(type_info_entry, name) + size);
2065 return ret->name;
2066}
2067
2068static void CDECL type_info_entry_free(void *ptr)
2069{
2070 ptr = (char*)ptr - FIELD_OFFSET(type_info_entry, name);
2072}
2073
2074/******************************************************************
2075 * __std_type_info_compare (UCRTBASE.@)
2076 */
2077int CDECL MSVCRT_type_info_compare(const type_info140 *l, const type_info140 *r)
2078{
2079 int ret;
2080
2081 if (l == r) ret = 0;
2082 else ret = MSVCRT_strcmp(l->mangled + 1, r->mangled + 1);
2083 TRACE("(%p %p) returning %d\n", l, r, ret);
2084 return ret;
2085}
2086
2087/******************************************************************
2088 * __std_type_info_name (UCRTBASE.@)
2089 */
2090const char* CDECL MSVCRT_type_info_name_list(type_info140 *ti, SLIST_HEADER *header)
2091{
2092 if (!ti->name)
2093 {
2094 char* name = __unDName(0, ti->mangled + 1, 0,
2095 type_info_entry_malloc, type_info_entry_free, UNDNAME_NO_ARGUMENTS | UNDNAME_32_BIT_DECODE);
2096 if (name)
2097 {
2098 unsigned int len = strlen(name);
2099
2100 while (len && name[--len] == ' ')
2101 name[len] = '\0';
2102
2103 if (InterlockedCompareExchangePointer((void**)&ti->name, name, NULL))
2104 {
2105 type_info_entry_free(name);
2106 }
2107 else
2108 {
2109 type_info_entry *entry = (type_info_entry*)(name-FIELD_OFFSET(type_info_entry, name));
2111 }
2112 }
2113 }
2114 TRACE("(%p) returning %s\n", ti, ti->name);
2115 return ti->name;
2116}
2117
2118/******************************************************************
2119 * __std_type_info_destroy_list (UCRTBASE.@)
2120 */
2121void CDECL MSVCRT_type_info_destroy_list(SLIST_HEADER *header)
2122{
2123 SLIST_ENTRY *cur, *next;
2124
2125 TRACE("(%p)\n", header);
2126
2128 {
2129 next = cur->Next;
2131 }
2132}
2133
2134/******************************************************************
2135 * __std_type_info_hash (UCRTBASE.@)
2136 */
2137MSVCRT_size_t CDECL MSVCRT_type_info_hash(const type_info140 *ti)
2138{
2139 MSVCRT_size_t hash, fnv_prime;
2140 const char *p;
2141
2142#ifdef _WIN64
2143 hash = 0xcbf29ce484222325;
2144 fnv_prime = 0x100000001b3;
2145#else
2146 hash = 0x811c9dc5;
2147 fnv_prime = 0x1000193;
2148#endif
2149
2150 TRACE("(%p)->%s\n", ti, ti->mangled);
2151
2152 for(p = ti->mangled+1; *p; p++) {
2153 hash ^= *p;
2154 hash *= fnv_prime;
2155 }
2156
2157#ifdef _WIN64
2158 hash ^= hash >> 32;
2159#endif
2160
2161 return hash;
2162}
2163
2164#endif /* _MSVCR_VER >= 140 */
2165
2166#if _MSVCR_VER >= 100
2167
2168enum ConcRT_EventType
2169{
2170 CONCRT_EVENT_GENERIC,
2171 CONCRT_EVENT_START,
2172 CONCRT_EVENT_END,
2173 CONCRT_EVENT_BLOCK,
2174 CONCRT_EVENT_UNBLOCK,
2175 CONCRT_EVENT_YIELD,
2176 CONCRT_EVENT_ATTACH,
2177 CONCRT_EVENT_DETACH
2178};
2179
2180/* ?_Trace_ppl_function@Concurrency@@YAXABU_GUID@@EW4ConcRT_EventType@1@@Z */
2181/* ?_Trace_ppl_function@Concurrency@@YAXAEBU_GUID@@EW4ConcRT_EventType@1@@Z */
2182void __cdecl Concurrency__Trace_ppl_function(const GUID *guid, unsigned char level, enum ConcRT_EventType type)
2183{
2184 FIXME("(%s %u %i) stub\n", debugstr_guid(guid), level, type);
2185}
2186
2187#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:114
r l[0]
Definition: byte_order.h:168
return
Definition: dirsup.c:529
FxCollectionEntry * Next(VOID)
#define __ASM_VTABLE(name, funcs)
Definition: cxx.h:40
#define VTABLE_ADD_FUNC(name)
Definition: cxx.h:38
#define DEFINE_RTTI_DATA0(name, off, mangled_name)
Definition: cxx.h:165
#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:658
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_opt_ const ULONG_PTR *lpArguments)
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:1647
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:1806
const type_info *CDECL MSVCRT___RTtypeid(void *cppobj)
Definition: cpp.c:1312
__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:1253
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:1572
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:1545
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:1213
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:999
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:1285
void CDECL MSVCRT_terminate(void)
Definition: cpp.c:1275
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:1231
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:1243
void *CDECL MSVCRT___RTDynamicCast(void *cppobj, int unknown, type_info *src, type_info *dst, int do_throw)
Definition: cpp.c:1401
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:192
this_ptr_offsets offsets
Definition: cxx.h:186
int num_base_classes
Definition: cxx.h:185
const type_info * type_descriptor
Definition: cxx.h:184
unsigned int attributes
Definition: cxx.h:187
const rtti_base_array * base_classes
Definition: cxx.h:200
const type_info * type_descriptor
Definition: cxx.h:208
unsigned int signature
Definition: cxx.h:205
int base_class_offset
Definition: cxx.h:206
const rtti_object_hierarchy * type_hierarchy
Definition: cxx.h:209
Definition: match.c:390
EXCEPTION_RECORD * rec
Definition: cpp.c:1706
int * ref
Definition: cpp.c:1707
Definition: _hash_fun.h:40
Definition: name.c:39
#define EH_NONCONTINUABLE
Definition: stubs.h:32
#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