2 * msvcrt.dll C++ objects
4 * Copyright 2000 Jon Griffiths
5 * Copyright 2003, 2004 Alexandre Julliard
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.
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.
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
27 #include "wine/exception.h"
28 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt
);
35 CREATE_TYPE_INFO_VTABLE
36 CREATE_EXCEPTION_OBJECT(exception
)
38 struct __type_info_node
41 struct __type_info_node
* next
;
44 typedef exception bad_cast
;
45 typedef exception bad_typeid
;
46 typedef exception __non_rtti_object
;
48 extern const vtable_ptr bad_typeid_vtable
;
49 extern const vtable_ptr bad_cast_vtable
;
50 extern const vtable_ptr __non_rtti_object_vtable
;
51 extern const vtable_ptr type_info_vtable
;
53 /* get the vtable pointer for a C++ object */
54 static inline const vtable_ptr
*get_vtable( void *obj
)
56 return *(const vtable_ptr
**)obj
;
59 static inline const rtti_object_locator
*get_obj_locator( void *cppobj
)
61 const vtable_ptr
*vtable
= get_vtable( cppobj
);
62 return (const rtti_object_locator
*)vtable
[-1];
66 static void dump_obj_locator( const rtti_object_locator
*ptr
)
69 const rtti_object_hierarchy
*h
= ptr
->type_hierarchy
;
71 TRACE( "%p: sig=%08x base_offset=%08x flags=%08x type=%p %s hierarchy=%p\n",
72 ptr
, ptr
->signature
, ptr
->base_class_offset
, ptr
->flags
,
73 ptr
->type_descriptor
, dbgstr_type_info(ptr
->type_descriptor
), ptr
->type_hierarchy
);
74 TRACE( " hierarchy: sig=%08x attr=%08x len=%d base classes=%p\n",
75 h
->signature
, h
->attributes
, h
->array_len
, h
->base_classes
);
76 for (i
= 0; i
< h
->array_len
; i
++)
78 TRACE( " base class %p: num %d off %d,%d,%d attr %08x type %p %s\n",
79 h
->base_classes
->bases
[i
],
80 h
->base_classes
->bases
[i
]->num_base_classes
,
81 h
->base_classes
->bases
[i
]->offsets
.this_offset
,
82 h
->base_classes
->bases
[i
]->offsets
.vbase_descr
,
83 h
->base_classes
->bases
[i
]->offsets
.vbase_offset
,
84 h
->base_classes
->bases
[i
]->attributes
,
85 h
->base_classes
->bases
[i
]->type_descriptor
,
86 dbgstr_type_info(h
->base_classes
->bases
[i
]->type_descriptor
) );
92 static void dump_obj_locator( const rtti_object_locator
*ptr
)
95 char *base
= ptr
->signature
== 0 ? RtlPcToFileHeader((void*)ptr
, (void**)&base
) : (char*)ptr
- ptr
->object_locator
;
96 const rtti_object_hierarchy
*h
= (const rtti_object_hierarchy
*)(base
+ ptr
->type_hierarchy
);
97 const type_info
*type_descriptor
= (const type_info
*)(base
+ ptr
->type_descriptor
);
99 TRACE( "%p: sig=%08x base_offset=%08x flags=%08x type=%p %s hierarchy=%p\n",
100 ptr
, ptr
->signature
, ptr
->base_class_offset
, ptr
->flags
,
101 type_descriptor
, dbgstr_type_info(type_descriptor
), h
);
102 TRACE( " hierarchy: sig=%08x attr=%08x len=%d base classes=%p\n",
103 h
->signature
, h
->attributes
, h
->array_len
, base
+ h
->base_classes
);
104 for (i
= 0; i
< h
->array_len
; i
++)
106 const rtti_base_descriptor
*bases
= (rtti_base_descriptor
*)(base
+
107 ((const rtti_base_array
*)(base
+ h
->base_classes
))->bases
[i
]);
109 TRACE( " base class %p: num %d off %d,%d,%d attr %08x type %p %s\n",
111 bases
->num_base_classes
,
112 bases
->offsets
.this_offset
,
113 bases
->offsets
.vbase_descr
,
114 bases
->offsets
.vbase_offset
,
116 base
+ bases
->type_descriptor
,
117 dbgstr_type_info((const type_info
*)(base
+ bases
->type_descriptor
)) );
122 /******************************************************************
123 * ??0exception@@QAE@ABQBD@Z (MSVCRT.@)
125 DEFINE_THISCALL_WRAPPER(exception_ctor
,8)
126 exception
* __thiscall
exception_ctor(exception
* _this
, const char ** name
)
128 TRACE("(%p,%s)\n", _this
, *name
);
129 return __exception_ctor(_this
, *name
, &exception_vtable
);
132 /******************************************************************
133 * ??0exception@@QAE@ABQBDH@Z (MSVCRT.@)
135 DEFINE_THISCALL_WRAPPER(exception_ctor_noalloc
,12)
136 exception
* __thiscall
exception_ctor_noalloc(exception
* _this
, char ** name
, int noalloc
)
138 TRACE("(%p,%s)\n", _this
, *name
);
139 _this
->vtable
= &exception_vtable
;
141 _this
->do_free
= FALSE
;
145 /******************************************************************
146 * ??0exception@@QAE@XZ (MSVCRT.@)
148 DEFINE_THISCALL_WRAPPER(exception_default_ctor
,4)
149 exception
* __thiscall
exception_default_ctor(exception
* _this
)
151 TRACE("(%p)\n", _this
);
152 return __exception_ctor(_this
, NULL
, &exception_vtable
);
155 /******************************************************************
156 * ??4exception@@QAEAAV0@ABV0@@Z (MSVCRT.@)
158 DEFINE_THISCALL_WRAPPER(exception_opequals
,8)
159 exception
* __thiscall
exception_opequals(exception
* _this
, const exception
* rhs
)
161 TRACE("(%p %p)\n", _this
, rhs
);
164 exception_dtor(_this
);
165 exception_copy_ctor(_this
, rhs
);
167 TRACE("name = %s\n", _this
->name
);
171 /******************************************************************
172 * ??_Gexception@@UAEPAXI@Z (MSVCRT.@)
174 DEFINE_THISCALL_WRAPPER(exception_scalar_dtor
,8)
175 void * __thiscall
exception_scalar_dtor(exception
* _this
, unsigned int flags
)
177 TRACE("(%p %x)\n", _this
, flags
);
178 exception_dtor(_this
);
179 if (flags
& 1) operator_delete(_this
);
183 /******************************************************************
184 * ??0bad_typeid@@QAE@ABV0@@Z (MSVCRT.@)
186 DEFINE_THISCALL_WRAPPER(bad_typeid_copy_ctor
,8)
187 bad_typeid
* __thiscall
bad_typeid_copy_ctor(bad_typeid
* _this
, const bad_typeid
* rhs
)
189 TRACE("(%p %p)\n", _this
, rhs
);
190 return __exception_copy_ctor(_this
, rhs
, &bad_typeid_vtable
);
193 /******************************************************************
194 * ??0bad_typeid@@QAE@PBD@Z (MSVCRT.@)
196 DEFINE_THISCALL_WRAPPER(bad_typeid_ctor
,8)
197 bad_typeid
* __thiscall
bad_typeid_ctor(bad_typeid
* _this
, const char * name
)
199 TRACE("(%p %s)\n", _this
, name
);
200 return __exception_ctor(_this
, name
, &bad_typeid_vtable
);
203 /******************************************************************
204 * ??_Fbad_typeid@@QAEXXZ (MSVCRT.@)
206 DEFINE_THISCALL_WRAPPER(bad_typeid_default_ctor
,4)
207 bad_typeid
* __thiscall
bad_typeid_default_ctor(bad_typeid
* _this
)
209 return bad_typeid_ctor( _this
, "bad typeid" );
212 /******************************************************************
213 * ??1bad_typeid@@UAE@XZ (MSVCRT.@)
215 DEFINE_THISCALL_WRAPPER(bad_typeid_dtor
,4)
216 void __thiscall
bad_typeid_dtor(bad_typeid
* _this
)
218 TRACE("(%p)\n", _this
);
219 exception_dtor(_this
);
222 /******************************************************************
223 * ??4bad_typeid@@QAEAAV0@ABV0@@Z (MSVCRT.@)
225 DEFINE_THISCALL_WRAPPER(bad_typeid_opequals
,8)
226 bad_typeid
* __thiscall
bad_typeid_opequals(bad_typeid
* _this
, const bad_typeid
* rhs
)
228 TRACE("(%p %p)\n", _this
, rhs
);
229 exception_opequals(_this
, rhs
);
233 /******************************************************************
234 * ??_Ebad_typeid@@UAEPAXI@Z (MSVCRT.@)
236 DEFINE_THISCALL_WRAPPER(bad_typeid_vector_dtor
,8)
237 void * __thiscall
bad_typeid_vector_dtor(bad_typeid
* _this
, unsigned int flags
)
239 TRACE("(%p %x)\n", _this
, flags
);
242 /* we have an array, with the number of elements stored before the first object */
243 INT_PTR i
, *ptr
= (INT_PTR
*)_this
- 1;
245 for (i
= *ptr
- 1; i
>= 0; i
--) bad_typeid_dtor(_this
+ i
);
246 operator_delete(ptr
);
250 bad_typeid_dtor(_this
);
251 if (flags
& 1) operator_delete(_this
);
256 /******************************************************************
257 * ??_Gbad_typeid@@UAEPAXI@Z (MSVCRT.@)
259 DEFINE_THISCALL_WRAPPER(bad_typeid_scalar_dtor
,8)
260 void * __thiscall
bad_typeid_scalar_dtor(bad_typeid
* _this
, unsigned int flags
)
262 TRACE("(%p %x)\n", _this
, flags
);
263 bad_typeid_dtor(_this
);
264 if (flags
& 1) operator_delete(_this
);
268 /******************************************************************
269 * ??0__non_rtti_object@@QAE@ABV0@@Z (MSVCRT.@)
271 DEFINE_THISCALL_WRAPPER(__non_rtti_object_copy_ctor
,8)
272 __non_rtti_object
* __thiscall
__non_rtti_object_copy_ctor(__non_rtti_object
* _this
,
273 const __non_rtti_object
* rhs
)
275 TRACE("(%p %p)\n", _this
, rhs
);
276 return __exception_copy_ctor(_this
, rhs
, &__non_rtti_object_vtable
);
279 /******************************************************************
280 * ??0__non_rtti_object@@QAE@PBD@Z (MSVCRT.@)
282 DEFINE_THISCALL_WRAPPER(__non_rtti_object_ctor
,8)
283 __non_rtti_object
* __thiscall
__non_rtti_object_ctor(__non_rtti_object
* _this
,
286 TRACE("(%p %s)\n", _this
, name
);
287 return __exception_ctor(_this
, name
, &__non_rtti_object_vtable
);
290 /******************************************************************
291 * ??1__non_rtti_object@@UAE@XZ (MSVCRT.@)
293 DEFINE_THISCALL_WRAPPER(__non_rtti_object_dtor
,4)
294 void __thiscall
__non_rtti_object_dtor(__non_rtti_object
* _this
)
296 TRACE("(%p)\n", _this
);
297 bad_typeid_dtor(_this
);
300 /******************************************************************
301 * ??4__non_rtti_object@@QAEAAV0@ABV0@@Z (MSVCRT.@)
303 DEFINE_THISCALL_WRAPPER(__non_rtti_object_opequals
,8)
304 __non_rtti_object
* __thiscall
__non_rtti_object_opequals(__non_rtti_object
* _this
,
305 const __non_rtti_object
*rhs
)
307 TRACE("(%p %p)\n", _this
, rhs
);
308 bad_typeid_opequals(_this
, rhs
);
312 /******************************************************************
313 * ??_E__non_rtti_object@@UAEPAXI@Z (MSVCRT.@)
315 DEFINE_THISCALL_WRAPPER(__non_rtti_object_vector_dtor
,8)
316 void * __thiscall
__non_rtti_object_vector_dtor(__non_rtti_object
* _this
, unsigned int flags
)
318 TRACE("(%p %x)\n", _this
, flags
);
321 /* we have an array, with the number of elements stored before the first object */
322 INT_PTR i
, *ptr
= (INT_PTR
*)_this
- 1;
324 for (i
= *ptr
- 1; i
>= 0; i
--) __non_rtti_object_dtor(_this
+ i
);
325 operator_delete(ptr
);
329 __non_rtti_object_dtor(_this
);
330 if (flags
& 1) operator_delete(_this
);
335 /******************************************************************
336 * ??_G__non_rtti_object@@UAEPAXI@Z (MSVCRT.@)
338 DEFINE_THISCALL_WRAPPER(__non_rtti_object_scalar_dtor
,8)
339 void * __thiscall
__non_rtti_object_scalar_dtor(__non_rtti_object
* _this
, unsigned int flags
)
341 TRACE("(%p %x)\n", _this
, flags
);
342 __non_rtti_object_dtor(_this
);
343 if (flags
& 1) operator_delete(_this
);
347 /******************************************************************
348 * ??0bad_cast@@AAE@PBQBD@Z (MSVCRT.@)
349 * ??0bad_cast@@QAE@ABQBD@Z (MSVCRT.@)
351 DEFINE_THISCALL_WRAPPER(bad_cast_ctor
,8)
352 bad_cast
* __thiscall
bad_cast_ctor(bad_cast
* _this
, const char ** name
)
354 TRACE("(%p %s)\n", _this
, *name
);
355 return __exception_ctor(_this
, *name
, &bad_cast_vtable
);
358 /******************************************************************
359 * ??0bad_cast@@QAE@ABV0@@Z (MSVCRT.@)
361 DEFINE_THISCALL_WRAPPER(bad_cast_copy_ctor
,8)
362 bad_cast
* __thiscall
bad_cast_copy_ctor(bad_cast
* _this
, const bad_cast
* rhs
)
364 TRACE("(%p %p)\n", _this
, rhs
);
365 return __exception_copy_ctor(_this
, rhs
, &bad_cast_vtable
);
368 /******************************************************************
369 * ??0bad_cast@@QAE@PBD@Z (MSVCRT.@)
371 DEFINE_THISCALL_WRAPPER(bad_cast_ctor_charptr
,8)
372 bad_cast
* __thiscall
bad_cast_ctor_charptr(bad_cast
* _this
, const char * name
)
374 TRACE("(%p %s)\n", _this
, name
);
375 return __exception_ctor(_this
, name
, &bad_cast_vtable
);
378 /******************************************************************
379 * ??_Fbad_cast@@QAEXXZ (MSVCRT.@)
381 DEFINE_THISCALL_WRAPPER(bad_cast_default_ctor
,4)
382 bad_cast
* __thiscall
bad_cast_default_ctor(bad_cast
* _this
)
384 return bad_cast_ctor_charptr( _this
, "bad cast" );
387 /******************************************************************
388 * ??1bad_cast@@UAE@XZ (MSVCRT.@)
390 DEFINE_THISCALL_WRAPPER(bad_cast_dtor
,4)
391 void __thiscall
bad_cast_dtor(bad_cast
* _this
)
393 TRACE("(%p)\n", _this
);
394 exception_dtor(_this
);
397 /******************************************************************
398 * ??4bad_cast@@QAEAAV0@ABV0@@Z (MSVCRT.@)
400 DEFINE_THISCALL_WRAPPER(bad_cast_opequals
,8)
401 bad_cast
* __thiscall
bad_cast_opequals(bad_cast
* _this
, const bad_cast
* rhs
)
403 TRACE("(%p %p)\n", _this
, rhs
);
404 exception_opequals(_this
, rhs
);
408 /******************************************************************
409 * ??_Ebad_cast@@UAEPAXI@Z (MSVCRT.@)
411 DEFINE_THISCALL_WRAPPER(bad_cast_vector_dtor
,8)
412 void * __thiscall
bad_cast_vector_dtor(bad_cast
* _this
, unsigned int flags
)
414 TRACE("(%p %x)\n", _this
, flags
);
417 /* we have an array, with the number of elements stored before the first object */
418 INT_PTR i
, *ptr
= (INT_PTR
*)_this
- 1;
420 for (i
= *ptr
- 1; i
>= 0; i
--) bad_cast_dtor(_this
+ i
);
421 operator_delete(ptr
);
425 bad_cast_dtor(_this
);
426 if (flags
& 1) operator_delete(_this
);
431 /******************************************************************
432 * ??_Gbad_cast@@UAEPAXI@Z (MSVCRT.@)
434 DEFINE_THISCALL_WRAPPER(bad_cast_scalar_dtor
,8)
435 void * __thiscall
bad_cast_scalar_dtor(bad_cast
* _this
, unsigned int flags
)
437 TRACE("(%p %x)\n", _this
, flags
);
438 bad_cast_dtor(_this
);
439 if (flags
& 1) operator_delete(_this
);
443 /******************************************************************
444 * ??8type_info@@QBEHABV0@@Z (MSVCRT.@)
446 DEFINE_THISCALL_WRAPPER(type_info_opequals_equals
,8)
447 int __thiscall
type_info_opequals_equals(type_info
* _this
, const type_info
* rhs
)
449 int ret
= !strcmp(_this
->mangled
+ 1, rhs
->mangled
+ 1);
450 TRACE("(%p %p) returning %d\n", _this
, rhs
, ret
);
454 /******************************************************************
455 * ??9type_info@@QBEHABV0@@Z (MSVCRT.@)
457 DEFINE_THISCALL_WRAPPER(type_info_opnot_equals
,8)
458 int __thiscall
type_info_opnot_equals(type_info
* _this
, const type_info
* rhs
)
460 int ret
= !!strcmp(_this
->mangled
+ 1, rhs
->mangled
+ 1);
461 TRACE("(%p %p) returning %d\n", _this
, rhs
, ret
);
465 /******************************************************************
466 * ?before@type_info@@QBEHABV1@@Z (MSVCRT.@)
468 DEFINE_THISCALL_WRAPPER(type_info_before
,8)
469 int __thiscall
type_info_before(type_info
* _this
, const type_info
* rhs
)
471 int ret
= strcmp(_this
->mangled
+ 1, rhs
->mangled
+ 1) < 0;
472 TRACE("(%p %p) returning %d\n", _this
, rhs
, ret
);
476 /******************************************************************
477 * ??1type_info@@UAE@XZ (MSVCRT.@)
479 DEFINE_THISCALL_WRAPPER(type_info_dtor
,4)
480 void __thiscall
type_info_dtor(type_info
* _this
)
482 TRACE("(%p)\n", _this
);
486 /******************************************************************
487 * ?name@type_info@@QBEPBDXZ (MSVCRT.@)
489 DEFINE_THISCALL_WRAPPER(type_info_name
,4)
490 const char * __thiscall
type_info_name(type_info
* _this
)
494 /* Create and set the demangled name */
495 /* Note: mangled name in type_info struct always starts with a '.', while
496 * it isn't valid for mangled name.
497 * Is this '.' really part of the mangled name, or has it some other meaning ?
499 char* name
= __unDName(0, _this
->mangled
+ 1, 0,
500 malloc
, free
, UNDNAME_NO_ARGUMENTS
| UNDNAME_32_BIT_DECODE
);
503 unsigned int len
= strlen(name
);
505 /* It seems _unDName may leave blanks at the end of the demangled name */
506 while (len
&& name
[--len
] == ' ')
509 if (InterlockedCompareExchangePointer((void**)&_this
->name
, name
, NULL
))
511 /* Another thread set this member since we checked above - use it */
516 TRACE("(%p) returning %s\n", _this
, _this
->name
);
520 /******************************************************************
521 * ?raw_name@type_info@@QBEPBDXZ (MSVCRT.@)
523 DEFINE_THISCALL_WRAPPER(type_info_raw_name
,4)
524 const char * __thiscall
type_info_raw_name(type_info
* _this
)
526 TRACE("(%p) returning %s\n", _this
, _this
->mangled
);
527 return _this
->mangled
;
532 typedef exception bad_alloc
;
533 extern const vtable_ptr bad_alloc_vtable
;
535 /* bad_alloc class implementation */
536 DEFINE_THISCALL_WRAPPER(bad_alloc_copy_ctor
,8)
537 bad_alloc
* __thiscall
bad_alloc_copy_ctor(bad_alloc
* _this
, const bad_alloc
* rhs
)
539 TRACE("(%p %p)\n", _this
, rhs
);
540 return __exception_copy_ctor(_this
, rhs
, &bad_alloc_vtable
);
543 DEFINE_THISCALL_WRAPPER(bad_alloc_dtor
,4)
544 void __thiscall
bad_alloc_dtor(bad_alloc
* _this
)
546 TRACE("(%p)\n", _this
);
547 exception_dtor(_this
);
550 #endif /* _MSVCR_VER >= 80 */
552 __ASM_BLOCK_BEGIN(vtables
)
555 __ASM_VTABLE(exception_old
,
556 VTABLE_ADD_FUNC(exception_vector_dtor
)
557 VTABLE_ADD_FUNC(exception_what
));
558 __ASM_VTABLE(bad_alloc
,
559 VTABLE_ADD_FUNC(exception_vector_dtor
)
560 VTABLE_ADD_FUNC(exception_what
));
562 __ASM_VTABLE(bad_typeid
,
563 VTABLE_ADD_FUNC(bad_typeid_vector_dtor
)
564 VTABLE_ADD_FUNC(exception_what
));
565 __ASM_VTABLE(bad_cast
,
566 VTABLE_ADD_FUNC(bad_cast_vector_dtor
)
567 VTABLE_ADD_FUNC(exception_what
));
568 __ASM_VTABLE(__non_rtti_object
,
569 VTABLE_ADD_FUNC(__non_rtti_object_vector_dtor
)
570 VTABLE_ADD_FUNC(exception_what
));
575 DEFINE_RTTI_DATA0( exception_old
, 0, ".?AVexception@@" )
576 DEFINE_RTTI_DATA1( bad_typeid
, 0, &exception_rtti_base_descriptor
, ".?AVbad_typeid@std@@" )
577 DEFINE_RTTI_DATA1( bad_cast
, 0, &exception_rtti_base_descriptor
, ".?AVbad_cast@std@@" )
578 DEFINE_RTTI_DATA2( __non_rtti_object
, 0, &bad_typeid_rtti_base_descriptor
, &exception_rtti_base_descriptor
, ".?AV__non_rtti_object@std@@" )
579 DEFINE_RTTI_DATA1( bad_alloc
, 0, &exception_rtti_base_descriptor
, ".?AVbad_alloc@std@@" )
581 DEFINE_RTTI_DATA1( bad_typeid
, 0, &exception_rtti_base_descriptor
, ".?AVbad_typeid@@" )
582 DEFINE_RTTI_DATA1( bad_cast
, 0, &exception_rtti_base_descriptor
, ".?AVbad_cast@@" )
583 DEFINE_RTTI_DATA2( __non_rtti_object
, 0, &bad_typeid_rtti_base_descriptor
, &exception_rtti_base_descriptor
, ".?AV__non_rtti_object@@" )
586 DEFINE_CXX_EXCEPTION0( exception
, exception_dtor
)
587 DEFINE_CXX_DATA1( bad_typeid
, &exception_cxx_type_info
, bad_typeid_dtor
)
588 DEFINE_CXX_DATA1( bad_cast
, &exception_cxx_type_info
, bad_cast_dtor
)
589 DEFINE_CXX_DATA2( __non_rtti_object
, &bad_typeid_cxx_type_info
,
590 &exception_cxx_type_info
, __non_rtti_object_dtor
)
592 DEFINE_CXX_DATA1( bad_alloc
, &exception_cxx_type_info
, bad_alloc_dtor
)
595 void msvcrt_init_exception(void *base
)
598 init_type_info_rtti(base
);
599 init_exception_rtti(base
);
601 init_exception_old_rtti(base
);
602 init_bad_alloc_rtti(base
);
604 init_bad_typeid_rtti(base
);
605 init_bad_cast_rtti(base
);
606 init___non_rtti_object_rtti(base
);
608 init_exception_cxx(base
);
609 init_bad_typeid_cxx(base
);
610 init_bad_cast_cxx(base
);
611 init___non_rtti_object_cxx(base
);
613 init_bad_alloc_cxx(base
);
619 void throw_bad_alloc(void)
622 __exception_ctor(&e
, "bad allocation", &bad_alloc_vtable
);
623 _CxxThrowException(&e
, &bad_alloc_exception_type
);
627 /******************************************************************
628 * ?set_terminate@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
630 * Install a handler to be called when terminate() is called.
633 * func [I] Handler function to install
636 * The previously installed handler function, if any.
638 terminate_function CDECL
set_terminate(terminate_function func
)
640 thread_data_t
*data
= msvcrt_get_thread_data();
641 terminate_function previous
= data
->terminate_handler
;
642 TRACE("(%p) returning %p\n",func
,previous
);
643 data
->terminate_handler
= func
;
647 /******************************************************************
648 * _get_terminate (MSVCRT.@)
650 terminate_function CDECL
_get_terminate(void)
652 thread_data_t
*data
= msvcrt_get_thread_data();
653 TRACE("returning %p\n", data
->terminate_handler
);
654 return data
->terminate_handler
;
657 /******************************************************************
658 * ?set_unexpected@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
660 * Install a handler to be called when unexpected() is called.
663 * func [I] Handler function to install
666 * The previously installed handler function, if any.
668 unexpected_function CDECL
set_unexpected(unexpected_function func
)
670 thread_data_t
*data
= msvcrt_get_thread_data();
671 unexpected_function previous
= data
->unexpected_handler
;
672 TRACE("(%p) returning %p\n",func
,previous
);
673 data
->unexpected_handler
= func
;
677 /******************************************************************
678 * _get_unexpected (MSVCRT.@)
680 unexpected_function CDECL
_get_unexpected(void)
682 thread_data_t
*data
= msvcrt_get_thread_data();
683 TRACE("returning %p\n", data
->unexpected_handler
);
684 return data
->unexpected_handler
;
687 /******************************************************************
688 * ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z (MSVCRT.@)
690 _se_translator_function CDECL
_set_se_translator(_se_translator_function func
)
692 thread_data_t
*data
= msvcrt_get_thread_data();
693 _se_translator_function previous
= data
->se_translator
;
694 TRACE("(%p) returning %p\n",func
,previous
);
695 data
->se_translator
= func
;
699 /******************************************************************
700 * ?terminate@@YAXXZ (MSVCRT.@)
702 * Default handler for an unhandled exception.
708 * This function does not return. Either control resumes from any
709 * handler installed by calling set_terminate(), or (by default) abort()
712 void CDECL
terminate(void)
714 thread_data_t
*data
= msvcrt_get_thread_data();
715 if (data
->terminate_handler
) data
->terminate_handler();
719 /******************************************************************
720 * ?unexpected@@YAXXZ (MSVCRT.@)
722 void CDECL
unexpected(void)
724 thread_data_t
*data
= msvcrt_get_thread_data();
725 if (data
->unexpected_handler
) data
->unexpected_handler();
730 /******************************************************************
731 * __RTtypeid (MSVCRT.@)
733 * Retrieve the Run Time Type Information (RTTI) for a C++ object.
736 * cppobj [I] C++ object to get type information for.
739 * Success: A type_info object describing cppobj.
740 * Failure: If the object to be cast has no RTTI, a __non_rtti_object
741 * exception is thrown. If cppobj is NULL, a bad_typeid exception
742 * is thrown. In either case, this function does not return.
745 * This function is usually called by compiler generated code as a result
746 * of using one of the C++ dynamic cast statements.
749 const type_info
* CDECL
__RTtypeid(void *cppobj
)
751 const type_info
*ret
;
756 bad_typeid_ctor( &e
, "Attempted a typeid of NULL pointer!" );
757 _CxxThrowException( &e
, &bad_typeid_exception_type
);
762 const rtti_object_locator
*obj_locator
= get_obj_locator( cppobj
);
763 ret
= obj_locator
->type_descriptor
;
768 __non_rtti_object_ctor( &e
, "Bad read pointer - no RTTI data!" );
769 _CxxThrowException( &e
, &__non_rtti_object_exception_type
);
777 const type_info
* CDECL
__RTtypeid(void *cppobj
)
779 const type_info
*ret
;
784 bad_typeid_ctor( &e
, "Attempted a typeid of NULL pointer!" );
785 _CxxThrowException( &e
, &bad_typeid_exception_type
);
790 const rtti_object_locator
*obj_locator
= get_obj_locator( cppobj
);
793 if(obj_locator
->signature
== 0)
794 base
= RtlPcToFileHeader((void*)obj_locator
, (void**)&base
);
796 base
= (char*)obj_locator
- obj_locator
->object_locator
;
798 ret
= (type_info
*)(base
+ obj_locator
->type_descriptor
);
803 __non_rtti_object_ctor( &e
, "Bad read pointer - no RTTI data!" );
804 _CxxThrowException( &e
, &__non_rtti_object_exception_type
);
811 /******************************************************************
812 * __RTDynamicCast (MSVCRT.@)
814 * Dynamically cast a C++ object to one of its base classes.
817 * cppobj [I] Any C++ object to cast
818 * unknown [I] Reserved, set to 0
819 * src [I] type_info object describing cppobj
820 * dst [I] type_info object describing the base class to cast to
821 * do_throw [I] TRUE = throw an exception if the cast fails, FALSE = don't
824 * Success: The address of cppobj, cast to the object described by dst.
825 * Failure: NULL, If the object to be cast has no RTTI, or dst is not a
826 * valid cast for cppobj. If do_throw is TRUE, a bad_cast exception
827 * is thrown and this function does not return.
830 * This function is usually called by compiler generated code as a result
831 * of using one of the C++ dynamic cast statements.
834 void* CDECL
__RTDynamicCast(void *cppobj
, int unknown
,
835 type_info
*src
, type_info
*dst
,
840 if (!cppobj
) return NULL
;
842 TRACE("obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)\n",
843 cppobj
, unknown
, src
, dbgstr_type_info(src
), dst
, dbgstr_type_info(dst
), do_throw
);
845 /* To cast an object at runtime:
846 * 1.Find out the true type of the object from the typeinfo at vtable[-1]
847 * 2.Search for the destination type in the class hierarchy
848 * 3.If destination type is found, return base object address + dest offset
849 * Otherwise, fail the cast
851 * FIXME: the unknown parameter doesn't seem to be used for anything
856 const rtti_object_locator
*obj_locator
= get_obj_locator( cppobj
);
857 const rtti_object_hierarchy
*obj_bases
= obj_locator
->type_hierarchy
;
858 const rtti_base_descriptor
* const* base_desc
= obj_bases
->base_classes
->bases
;
860 if (TRACE_ON(msvcrt
)) dump_obj_locator(obj_locator
);
863 for (i
= 0; i
< obj_bases
->array_len
; i
++)
865 const type_info
*typ
= base_desc
[i
]->type_descriptor
;
867 if (!strcmp(typ
->mangled
, dst
->mangled
))
869 /* compute the correct this pointer for that base class */
870 void *this_ptr
= (char *)cppobj
- obj_locator
->base_class_offset
;
871 ret
= get_this_pointer( &base_desc
[i
]->offsets
, this_ptr
);
875 /* VC++ sets do_throw to 1 when the result of a dynamic_cast is assigned
876 * to a reference, since references cannot be NULL.
878 if (!ret
&& do_throw
)
880 const char *msg
= "Bad dynamic_cast!";
882 bad_cast_ctor( &e
, &msg
);
883 _CxxThrowException( &e
, &bad_cast_exception_type
);
889 __non_rtti_object_ctor( &e
, "Access violation - no RTTI data!" );
890 _CxxThrowException( &e
, &__non_rtti_object_exception_type
);
898 void* CDECL
__RTDynamicCast(void *cppobj
, int unknown
,
899 type_info
*src
, type_info
*dst
,
904 if (!cppobj
) return NULL
;
906 TRACE("obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)\n",
907 cppobj
, unknown
, src
, dbgstr_type_info(src
), dst
, dbgstr_type_info(dst
), do_throw
);
912 const rtti_object_locator
*obj_locator
= get_obj_locator( cppobj
);
913 const rtti_object_hierarchy
*obj_bases
;
914 const rtti_base_array
*base_array
;
917 if (TRACE_ON(msvcrt
)) dump_obj_locator(obj_locator
);
919 if(obj_locator
->signature
== 0)
920 base
= RtlPcToFileHeader((void*)obj_locator
, (void**)&base
);
922 base
= (char*)obj_locator
- obj_locator
->object_locator
;
924 obj_bases
= (const rtti_object_hierarchy
*)(base
+ obj_locator
->type_hierarchy
);
925 base_array
= (const rtti_base_array
*)(base
+ obj_bases
->base_classes
);
928 for (i
= 0; i
< obj_bases
->array_len
; i
++)
930 const rtti_base_descriptor
*base_desc
= (const rtti_base_descriptor
*)(base
+ base_array
->bases
[i
]);
931 const type_info
*typ
= (const type_info
*)(base
+ base_desc
->type_descriptor
);
933 if (!strcmp(typ
->mangled
, dst
->mangled
))
935 void *this_ptr
= (char *)cppobj
- obj_locator
->base_class_offset
;
936 ret
= get_this_pointer( &base_desc
->offsets
, this_ptr
);
940 if (!ret
&& do_throw
)
942 const char *msg
= "Bad dynamic_cast!";
944 bad_cast_ctor( &e
, &msg
);
945 _CxxThrowException( &e
, &bad_cast_exception_type
);
951 __non_rtti_object_ctor( &e
, "Access violation - no RTTI data!" );
952 _CxxThrowException( &e
, &__non_rtti_object_exception_type
);
960 /******************************************************************
961 * __RTCastToVoid (MSVCRT.@)
963 * Dynamically cast a C++ object to a void*.
966 * cppobj [I] The C++ object to cast
969 * Success: The base address of the object as a void*.
970 * Failure: NULL, if cppobj is NULL or has no RTTI.
973 * This function is usually called by compiler generated code as a result
974 * of using one of the C++ dynamic cast statements.
976 void* CDECL
__RTCastToVoid(void *cppobj
)
980 if (!cppobj
) return NULL
;
984 const rtti_object_locator
*obj_locator
= get_obj_locator( cppobj
);
985 ret
= (char *)cppobj
- obj_locator
->base_class_offset
;
990 __non_rtti_object_ctor( &e
, "Access violation - no RTTI data!" );
991 _CxxThrowException( &e
, &__non_rtti_object_exception_type
);
998 /*********************************************************************
999 * _CxxThrowException (MSVCRT.@)
1002 void WINAPI
_CxxThrowException( void *object
, const cxx_exception_type
*type
)
1006 args
[0] = CXX_FRAME_MAGIC_VC6
;
1007 args
[1] = (ULONG_PTR
)object
;
1008 args
[2] = (ULONG_PTR
)type
;
1009 RaiseException( CXX_EXCEPTION
, EH_NONCONTINUABLE
, 3, args
);
1012 void WINAPI
_CxxThrowException( void *object
, const cxx_exception_type
*type
)
1016 args
[0] = CXX_FRAME_MAGIC_VC6
;
1017 args
[1] = (ULONG_PTR
)object
;
1018 args
[2] = (ULONG_PTR
)type
;
1019 RtlPcToFileHeader( (void*)type
, (void**)&args
[3]);
1020 RaiseException( CXX_EXCEPTION
, EH_NONCONTINUABLE
, 4, args
);
1024 #if _MSVCR_VER >= 80
1026 /*********************************************************************
1027 * ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z
1028 * ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z
1031 int __cdecl
_is_exception_typeof(const type_info
*ti
, EXCEPTION_POINTERS
*ep
)
1035 TRACE("(%p %p)\n", ti
, ep
);
1039 EXCEPTION_RECORD
*rec
= ep
->ExceptionRecord
;
1041 if (rec
->ExceptionCode
==CXX_EXCEPTION
&& rec
->NumberParameters
==3 &&
1042 (rec
->ExceptionInformation
[0]==CXX_FRAME_MAGIC_VC6
||
1043 rec
->ExceptionInformation
[0]==CXX_FRAME_MAGIC_VC7
||
1044 rec
->ExceptionInformation
[0]==CXX_FRAME_MAGIC_VC8
))
1046 const cxx_type_info_table
*tit
= ((cxx_exception_type
*)rec
->ExceptionInformation
[2])->type_info_table
;
1049 for (i
=0; i
<tit
->count
; i
++) {
1050 if (ti
==tit
->info
[i
]->type_info
|| !strcmp(ti
->mangled
, tit
->info
[i
]->type_info
->mangled
))
1057 if (i
== tit
->count
)
1069 int __cdecl
_is_exception_typeof(const type_info
*ti
, EXCEPTION_POINTERS
*ep
)
1073 TRACE("(%p %p)\n", ti
, ep
);
1077 EXCEPTION_RECORD
*rec
= ep
->ExceptionRecord
;
1079 if (rec
->ExceptionCode
==CXX_EXCEPTION
&& rec
->NumberParameters
==4 &&
1080 (rec
->ExceptionInformation
[0]==CXX_FRAME_MAGIC_VC6
||
1081 rec
->ExceptionInformation
[0]==CXX_FRAME_MAGIC_VC7
||
1082 rec
->ExceptionInformation
[0]==CXX_FRAME_MAGIC_VC8
))
1084 const cxx_exception_type
*et
= (cxx_exception_type
*)rec
->ExceptionInformation
[2];
1085 const cxx_type_info_table
*tit
= (const cxx_type_info_table
*)(rec
->ExceptionInformation
[3]+et
->type_info_table
);
1088 for (i
=0; i
<tit
->count
; i
++) {
1089 const cxx_type_info
*cti
= (const cxx_type_info
*)(rec
->ExceptionInformation
[3]+tit
->info
[i
]);
1090 const type_info
*except_ti
= (const type_info
*)(rec
->ExceptionInformation
[3]+cti
->type_info
);
1091 if (ti
==except_ti
|| !strcmp(ti
->mangled
, except_ti
->mangled
))
1098 if (i
== tit
->count
)
1111 /*********************************************************************
1112 * __clean_type_info_names_internal (MSVCR80.@)
1114 void CDECL
__clean_type_info_names_internal(void *p
)
1116 FIXME("(%p) stub\n", p
);
1119 /*********************************************************************
1120 * ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z (MSVCR100.@)
1122 DEFINE_THISCALL_WRAPPER(type_info_name_internal_method
,8)
1123 const char * __thiscall
type_info_name_internal_method(type_info
* _this
, struct __type_info_node
*node
)
1126 if (node
&& !once
++) FIXME("type_info_node parameter ignored\n");
1128 return type_info_name(_this
);
1131 #endif /* _MSVCR_VER >= 80 */
1133 /* std::exception_ptr class helpers */
1136 EXCEPTION_RECORD
*rec
;
1137 LONG
*ref
; /* not binary compatible with native msvcr100 */
1140 #if _MSVCR_VER >= 100
1142 /*********************************************************************
1143 * ?__ExceptionPtrCreate@@YAXPAX@Z
1144 * ?__ExceptionPtrCreate@@YAXPEAX@Z
1146 void __cdecl
__ExceptionPtrCreate(exception_ptr
*ep
)
1148 TRACE("(%p)\n", ep
);
1154 #ifdef __ASM_USE_THISCALL_WRAPPER
1155 extern void call_dtor(const cxx_exception_type
*type
, void *func
, void *object
);
1157 __ASM_GLOBAL_FUNC( call_dtor
,
1158 "movl 12(%esp),%ecx\n\t"
1162 static inline void call_dtor(const cxx_exception_type
*type
, unsigned int dtor
, void *object
)
1164 char *base
= RtlPcToFileHeader((void*)type
, (void**)&base
);
1165 void (__cdecl
*func
)(void*) = (void*)(base
+ dtor
);
1169 #define call_dtor(type, func, object) ((void (__thiscall*)(void*))(func))(object)
1172 /*********************************************************************
1173 * ?__ExceptionPtrDestroy@@YAXPAX@Z
1174 * ?__ExceptionPtrDestroy@@YAXPEAX@Z
1176 void __cdecl
__ExceptionPtrDestroy(exception_ptr
*ep
)
1178 TRACE("(%p)\n", ep
);
1183 if (!InterlockedDecrement(ep
->ref
))
1185 if (ep
->rec
->ExceptionCode
== CXX_EXCEPTION
)
1187 const cxx_exception_type
*type
= (void*)ep
->rec
->ExceptionInformation
[2];
1188 void *obj
= (void*)ep
->rec
->ExceptionInformation
[1];
1190 if (type
&& type
->destructor
) call_dtor(type
, type
->destructor
, obj
);
1191 HeapFree(GetProcessHeap(), 0, obj
);
1194 HeapFree(GetProcessHeap(), 0, ep
->rec
);
1195 HeapFree(GetProcessHeap(), 0, ep
->ref
);
1199 /*********************************************************************
1200 * ?__ExceptionPtrCopy@@YAXPAXPBX@Z
1201 * ?__ExceptionPtrCopy@@YAXPEAXPEBX@Z
1203 void __cdecl
__ExceptionPtrCopy(exception_ptr
*ep
, const exception_ptr
*copy
)
1205 TRACE("(%p %p)\n", ep
, copy
);
1207 /* don't destroy object stored in ep */
1210 InterlockedIncrement(copy
->ref
);
1213 /*********************************************************************
1214 * ?__ExceptionPtrAssign@@YAXPAXPBX@Z
1215 * ?__ExceptionPtrAssign@@YAXPEAXPEBX@Z
1217 void __cdecl
__ExceptionPtrAssign(exception_ptr
*ep
, const exception_ptr
*assign
)
1219 TRACE("(%p %p)\n", ep
, assign
);
1221 /* don't destroy object stored in ep */
1223 InterlockedDecrement(ep
->ref
);
1227 InterlockedIncrement(ep
->ref
);
1230 #endif /* _MSVCR_VER >= 100 */
1232 /*********************************************************************
1233 * ?__ExceptionPtrRethrow@@YAXPBX@Z
1234 * ?__ExceptionPtrRethrow@@YAXPEBX@Z
1236 void __cdecl
__ExceptionPtrRethrow(const exception_ptr
*ep
)
1238 TRACE("(%p)\n", ep
);
1242 static const char *exception_msg
= "bad exception";
1245 exception_ctor(&e
, &exception_msg
);
1246 _CxxThrowException(&e
, &exception_exception_type
);
1250 RaiseException(ep
->rec
->ExceptionCode
, ep
->rec
->ExceptionFlags
& (~EH_UNWINDING
),
1251 ep
->rec
->NumberParameters
, ep
->rec
->ExceptionInformation
);
1254 #if _MSVCR_VER >= 100
1257 extern void call_copy_ctor( void *func
, void *this, void *src
, int has_vbase
);
1259 static inline void call_copy_ctor( void *func
, void *this, void *src
, int has_vbase
)
1261 TRACE( "calling copy ctor %p object %p src %p\n", func
, this, src
);
1263 ((void (__cdecl
*)(void*, void*, BOOL
))func
)(this, src
, 1);
1265 ((void (__cdecl
*)(void*, void*))func
)(this, src
);
1269 /*********************************************************************
1270 * ?__ExceptionPtrCurrentException@@YAXPAX@Z
1271 * ?__ExceptionPtrCurrentException@@YAXPEAX@Z
1274 void __cdecl
__ExceptionPtrCurrentException(exception_ptr
*ep
)
1276 EXCEPTION_RECORD
*rec
= msvcrt_get_thread_data()->exc_record
;
1278 TRACE("(%p)\n", ep
);
1287 ep
->rec
= HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD
));
1288 ep
->ref
= HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1293 if (ep
->rec
->ExceptionCode
== CXX_EXCEPTION
)
1295 const cxx_exception_type
*et
= (void*)ep
->rec
->ExceptionInformation
[2];
1296 const cxx_type_info
*ti
;
1299 ti
= et
->type_info_table
->info
[0];
1300 data
= HeapAlloc(GetProcessHeap(), 0, ti
->size
);
1302 obj
= (void*)ep
->rec
->ExceptionInformation
[1];
1303 if (ti
->flags
& CLASS_IS_SIMPLE_TYPE
)
1305 memcpy(data
, obj
, ti
->size
);
1306 if (ti
->size
== sizeof(void *)) *data
= get_this_pointer(&ti
->offsets
, *data
);
1308 else if (ti
->copy_ctor
)
1310 call_copy_ctor(ti
->copy_ctor
, data
, get_this_pointer(&ti
->offsets
, obj
),
1311 ti
->flags
& CLASS_HAS_VIRTUAL_BASE_CLASS
);
1314 memcpy(data
, get_this_pointer(&ti
->offsets
, obj
), ti
->size
);
1315 ep
->rec
->ExceptionInformation
[1] = (ULONG_PTR
)data
;
1320 void __cdecl
__ExceptionPtrCurrentException(exception_ptr
*ep
)
1322 EXCEPTION_RECORD
*rec
= msvcrt_get_thread_data()->exc_record
;
1324 TRACE("(%p)\n", ep
);
1333 ep
->rec
= HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD
));
1334 ep
->ref
= HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1339 if (ep
->rec
->ExceptionCode
== CXX_EXCEPTION
)
1341 const cxx_exception_type
*et
= (void*)ep
->rec
->ExceptionInformation
[2];
1342 const cxx_type_info
*ti
;
1344 char *base
= RtlPcToFileHeader((void*)et
, (void**)&base
);
1346 ti
= (const cxx_type_info
*)(base
+ ((const cxx_type_info_table
*)(base
+ et
->type_info_table
))->info
[0]);
1347 data
= HeapAlloc(GetProcessHeap(), 0, ti
->size
);
1349 obj
= (void*)ep
->rec
->ExceptionInformation
[1];
1350 if (ti
->flags
& CLASS_IS_SIMPLE_TYPE
)
1352 memcpy(data
, obj
, ti
->size
);
1353 if (ti
->size
== sizeof(void *)) *data
= get_this_pointer(&ti
->offsets
, *data
);
1355 else if (ti
->copy_ctor
)
1357 call_copy_ctor(base
+ ti
->copy_ctor
, data
, get_this_pointer(&ti
->offsets
, obj
),
1358 ti
->flags
& CLASS_HAS_VIRTUAL_BASE_CLASS
);
1361 memcpy(data
, get_this_pointer(&ti
->offsets
, obj
), ti
->size
);
1362 ep
->rec
->ExceptionInformation
[1] = (ULONG_PTR
)data
;
1368 #endif /* _MSVCR_VER >= 100 */
1370 #if _MSVCR_VER >= 110
1371 /*********************************************************************
1372 * ?__ExceptionPtrToBool@@YA_NPBX@Z
1373 * ?__ExceptionPtrToBool@@YA_NPEBX@Z
1375 bool __cdecl
__ExceptionPtrToBool(exception_ptr
*ep
)
1381 #if _MSVCR_VER >= 100
1383 /*********************************************************************
1384 * ?__ExceptionPtrCopyException@@YAXPAXPBX1@Z
1385 * ?__ExceptionPtrCopyException@@YAXPEAXPEBX1@Z
1388 void __cdecl
__ExceptionPtrCopyException(exception_ptr
*ep
,
1389 exception
*object
, const cxx_exception_type
*type
)
1391 const cxx_type_info
*ti
;
1394 __ExceptionPtrDestroy(ep
);
1396 ep
->rec
= HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD
));
1397 ep
->ref
= HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1400 memset(ep
->rec
, 0, sizeof(EXCEPTION_RECORD
));
1401 ep
->rec
->ExceptionCode
= CXX_EXCEPTION
;
1402 ep
->rec
->ExceptionFlags
= EH_NONCONTINUABLE
;
1403 ep
->rec
->NumberParameters
= 3;
1404 ep
->rec
->ExceptionInformation
[0] = CXX_FRAME_MAGIC_VC6
;
1405 ep
->rec
->ExceptionInformation
[2] = (ULONG_PTR
)type
;
1407 ti
= type
->type_info_table
->info
[0];
1408 data
= HeapAlloc(GetProcessHeap(), 0, ti
->size
);
1409 if (ti
->flags
& CLASS_IS_SIMPLE_TYPE
)
1411 memcpy(data
, object
, ti
->size
);
1412 if (ti
->size
== sizeof(void *)) *data
= get_this_pointer(&ti
->offsets
, *data
);
1414 else if (ti
->copy_ctor
)
1416 call_copy_ctor(ti
->copy_ctor
, data
, get_this_pointer(&ti
->offsets
, object
),
1417 ti
->flags
& CLASS_HAS_VIRTUAL_BASE_CLASS
);
1420 memcpy(data
, get_this_pointer(&ti
->offsets
, object
), ti
->size
);
1421 ep
->rec
->ExceptionInformation
[1] = (ULONG_PTR
)data
;
1424 void __cdecl
__ExceptionPtrCopyException(exception_ptr
*ep
,
1425 exception
*object
, const cxx_exception_type
*type
)
1427 const cxx_type_info
*ti
;
1431 RtlPcToFileHeader((void*)type
, (void**)&base
);
1432 __ExceptionPtrDestroy(ep
);
1434 ep
->rec
= HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD
));
1435 ep
->ref
= HeapAlloc(GetProcessHeap(), 0, sizeof(int));
1438 memset(ep
->rec
, 0, sizeof(EXCEPTION_RECORD
));
1439 ep
->rec
->ExceptionCode
= CXX_EXCEPTION
;
1440 ep
->rec
->ExceptionFlags
= EH_NONCONTINUABLE
;
1441 ep
->rec
->NumberParameters
= 4;
1442 ep
->rec
->ExceptionInformation
[0] = CXX_FRAME_MAGIC_VC6
;
1443 ep
->rec
->ExceptionInformation
[2] = (ULONG_PTR
)type
;
1444 ep
->rec
->ExceptionInformation
[3] = (ULONG_PTR
)base
;
1446 ti
= (const cxx_type_info
*)(base
+ ((const cxx_type_info_table
*)(base
+ type
->type_info_table
))->info
[0]);
1447 data
= HeapAlloc(GetProcessHeap(), 0, ti
->size
);
1448 if (ti
->flags
& CLASS_IS_SIMPLE_TYPE
)
1450 memcpy(data
, object
, ti
->size
);
1451 if (ti
->size
== sizeof(void *)) *data
= get_this_pointer(&ti
->offsets
, *data
);
1453 else if (ti
->copy_ctor
)
1455 call_copy_ctor(base
+ ti
->copy_ctor
, data
, get_this_pointer(&ti
->offsets
, object
),
1456 ti
->flags
& CLASS_HAS_VIRTUAL_BASE_CLASS
);
1459 memcpy(data
, get_this_pointer(&ti
->offsets
, object
), ti
->size
);
1460 ep
->rec
->ExceptionInformation
[1] = (ULONG_PTR
)data
;
1464 bool __cdecl
__ExceptionPtrCompare(const exception_ptr
*ep1
, const exception_ptr
*ep2
)
1466 return ep1
->rec
== ep2
->rec
;
1469 #endif /* _MSVCR_VER >= 100 */
1471 #if _MSVCR_VER >= 80
1472 void* __cdecl
__AdjustPointer(void *obj
, const this_ptr_offsets
*off
)
1474 return get_this_pointer(off
, obj
);
1478 #if _MSVCR_VER >= 140
1492 static void* CDECL
type_info_entry_malloc(size_t size
)
1494 type_info_entry
*ret
= malloc(FIELD_OFFSET(type_info_entry
, name
) + size
);
1498 static void CDECL
type_info_entry_free(void *ptr
)
1500 ptr
= (char*)ptr
- FIELD_OFFSET(type_info_entry
, name
);
1504 /******************************************************************
1505 * __std_type_info_compare (UCRTBASE.@)
1507 int CDECL
__std_type_info_compare(const type_info140
*l
, const type_info140
*r
)
1511 if (l
== r
) ret
= 0;
1512 else ret
= strcmp(l
->mangled
+ 1, r
->mangled
+ 1);
1513 TRACE("(%p %p) returning %d\n", l
, r
, ret
);
1517 /******************************************************************
1518 * __std_type_info_name (UCRTBASE.@)
1520 const char* CDECL
__std_type_info_name(type_info140
*ti
, SLIST_HEADER
*header
)
1524 char* name
= __unDName(0, ti
->mangled
+ 1, 0,
1525 type_info_entry_malloc
, type_info_entry_free
, UNDNAME_NO_ARGUMENTS
| UNDNAME_32_BIT_DECODE
);
1528 unsigned int len
= strlen(name
);
1530 while (len
&& name
[--len
] == ' ')
1533 if (InterlockedCompareExchangePointer((void**)&ti
->name
, name
, NULL
))
1535 type_info_entry_free(name
);
1539 type_info_entry
*entry
= (type_info_entry
*)(name
-FIELD_OFFSET(type_info_entry
, name
));
1540 InterlockedPushEntrySList(header
, &entry
->entry
);
1544 TRACE("(%p) returning %s\n", ti
, ti
->name
);
1548 /******************************************************************
1549 * __std_type_info_destroy_list (UCRTBASE.@)
1551 void CDECL
__std_type_info_destroy_list(SLIST_HEADER
*header
)
1553 SLIST_ENTRY
*cur
, *next
;
1555 TRACE("(%p)\n", header
);
1557 for(cur
= InterlockedFlushSList(header
); cur
; cur
= next
)
1564 /******************************************************************
1565 * __std_type_info_hash (UCRTBASE.@)
1567 size_t CDECL
__std_type_info_hash(const type_info140
*ti
)
1569 size_t hash
, fnv_prime
;
1573 hash
= 0xcbf29ce484222325;
1574 fnv_prime
= 0x100000001b3;
1577 fnv_prime
= 0x1000193;
1580 TRACE("(%p)->%s\n", ti
, ti
->mangled
);
1582 for(p
= ti
->mangled
+1; *p
; p
++) {
1594 #endif /* _MSVCR_VER >= 140 */