https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9efafd640f079d584dba89...
commit 9efafd640f079d584dba899b191d095af46eeb3b Author: Timo Kreuzer timo.kreuzer@reactos.org AuthorDate: Mon Jan 13 13:41:24 2020 +0100 Commit: Timo Kreuzer timo.kreuzer@reactos.org CommitDate: Sun Feb 9 15:56:30 2020 +0100
[CRT] Import wine exception handling code
The code is mostly unchanged. This includes the following changes: * Move all wine code to crt/wine to keep it separated from our own code * Add a minimal winternl.h * Remove the asm macros from wine/config.h * Include wine/asm.h where required * Fix the names of the exported functions (GCC uses thiscall now and no wrappers are used anymore) --- dll/win32/mshtml/ifacewrap.c | 1 + dll/win32/msi/custom.c | 1 + dll/win32/msvcrt/msvcrt.spec | 96 +- dll/win32/msvcrt40/msvcrt40.spec | 64 +- sdk/include/reactos/wine/asm.h | 4 + sdk/include/reactos/wine/config.h | 37 - sdk/include/reactos/wine/exception.h | 3 + sdk/lib/crt/crt.cmake | 23 +- sdk/lib/crt/except/amd64/ehandler.c | 12 +- sdk/lib/crt/except/amd64/seh.s | 6 - sdk/lib/crt/except/cpp.c | 1266 ----------------- sdk/lib/crt/except/cppexcept.c | 596 -------- sdk/lib/crt/except/except.c | 338 ----- sdk/lib/crt/except/i386/cpp.s | 148 +- sdk/lib/crt/except/i386/unwind.c | 39 - sdk/lib/crt/except/matherr.c | 16 - sdk/lib/crt/except/xcptfil.c | 98 -- sdk/lib/crt/include/internal/wine_msc.h | 148 +- sdk/lib/crt/wine/cpp.c | 2189 ++++++++++++++++++++++++++++++ sdk/lib/crt/{except => wine}/cppexcept.h | 48 +- sdk/lib/crt/wine/cxx.h | 267 ++++ sdk/lib/crt/wine/except.c | 545 ++++++++ sdk/lib/crt/wine/except_arm.c | 147 ++ sdk/lib/crt/wine/except_arm64.c | 148 ++ sdk/lib/crt/wine/except_i386.c | 1235 +++++++++++++++++ sdk/lib/crt/wine/except_x86_64.c | 758 +++++++++++ sdk/lib/crt/wine/msvcrt.h | 1494 ++++++++++++++++++++ sdk/lib/crt/wine/mtdll.h | 74 + sdk/lib/crt/wine/winternl.h | 313 +++++ 29 files changed, 7504 insertions(+), 2610 deletions(-)
diff --git a/dll/win32/mshtml/ifacewrap.c b/dll/win32/mshtml/ifacewrap.c index cc22246a72b..e78464d88b0 100644 --- a/dll/win32/mshtml/ifacewrap.c +++ b/dll/win32/mshtml/ifacewrap.c @@ -17,6 +17,7 @@ */
#include "mshtml_private.h" +#include <wine/asm.h>
/* * This object wraps any unrecognized interface overriding its IUnknown methods, allowing diff --git a/dll/win32/msi/custom.c b/dll/win32/msi/custom.c index 310a1441738..8680b7214b3 100644 --- a/dll/win32/msi/custom.c +++ b/dll/win32/msi/custom.c @@ -20,6 +20,7 @@
#include "config.h" #include "wine/port.h" +#include "wine/asm.h"
#define COBJMACROS
diff --git a/dll/win32/msvcrt/msvcrt.spec b/dll/win32/msvcrt/msvcrt.spec index 576b9800eb0..4e0c07aa950 100644 --- a/dll/win32/msvcrt/msvcrt.spec +++ b/dll/win32/msvcrt/msvcrt.spec @@ -1,64 +1,64 @@ # msvcrt.dll - MS VC++ Run Time Library
# **************** x86 C++ functions **************** -@ cdecl -i386 -norelay ??0__non_rtti_object@@QAE@ABV0@@Z(ptr) __thiscall_MSVCRT___non_rtti_object_copy_ctor # public: __thiscall __non_rtti_object::__non_rtti_object(class __non_rtti_object const &) -@ cdecl -i386 -norelay ??0__non_rtti_object@@QAE@PBD@Z(ptr) __thiscall_MSVCRT___non_rtti_object_ctor # public: __thiscall __non_rtti_object::__non_rtti_object(char const *) -@ cdecl -i386 -norelay ??0bad_cast@@AAE@PBQBD@Z(ptr) __thiscall_MSVCRT_bad_cast_ctor # private: __thiscall bad_cast::bad_cast(char const * const *) -@ cdecl -i386 -norelay ??0bad_cast@@QAE@ABQBD@Z(ptr) __thiscall_MSVCRT_bad_cast_ctor # public: __thiscall bad_cast::bad_cast(char const * const &) -@ cdecl -i386 -norelay ??0bad_cast@@QAE@ABV0@@Z(ptr) __thiscall_MSVCRT_bad_cast_copy_ctor # public: __thiscall bad_cast::bad_cast(class bad_cast const &) -@ cdecl -i386 -norelay ??0bad_cast@@QAE@PBD@Z(ptr) __thiscall_MSVCRT_bad_cast_ctor_charptr # public: __thiscall bad_cast::bad_cast(char const *) -@ cdecl -i386 -norelay ??0bad_typeid@@QAE@ABV0@@Z(ptr) __thiscall_MSVCRT_bad_typeid_copy_ctor # public: __thiscall bad_typeid::bad_typeid(class bad_typeid const &) -@ cdecl -i386 -norelay ??0bad_typeid@@QAE@PBD@Z(ptr) __thiscall_MSVCRT_bad_typeid_ctor # public: __thiscall bad_typeid::bad_typeid(char const *) -@ cdecl -i386 -norelay ??0exception@@QAE@ABQBD@Z(ptr) __thiscall_MSVCRT_exception_ctor # public: __thiscall exception::exception(char const * const &) -@ cdecl -i386 -norelay ??0exception@@QAE@ABQBDH@Z(ptr long) __thiscall_MSVCRT_exception_ctor_noalloc # public: __thiscall exception::exception(char const * const &,int) -@ cdecl -i386 -norelay ??0exception@@QAE@ABV0@@Z(ptr) __thiscall_MSVCRT_exception_copy_ctor # public: __thiscall exception::exception(class exception const &) -@ cdecl -i386 -norelay ??0exception@@QAE@XZ() __thiscall_MSVCRT_exception_default_ctor # public: __thiscall exception::exception(void) -@ cdecl -i386 -norelay ??1__non_rtti_object@@UAE@XZ() __thiscall_MSVCRT___non_rtti_object_dtor # public: virtual __thiscall __non_rtti_object::~__non_rtti_object(void) -@ cdecl -i386 -norelay ??1bad_cast@@UAE@XZ() __thiscall_MSVCRT_bad_cast_dtor # public: virtual __thiscall bad_cast::~bad_cast(void) -@ cdecl -i386 -norelay ??1bad_typeid@@UAE@XZ() __thiscall_MSVCRT_bad_typeid_dtor # public: virtual __thiscall bad_typeid::~bad_typeid(void) -@ cdecl -i386 -norelay ??1exception@@UAE@XZ() __thiscall_MSVCRT_exception_dtor # public: virtual __thiscall exception::~exception(void) -@ cdecl -i386 -norelay ??1type_info@@UAE@XZ() __thiscall_MSVCRT_type_info_dtor # public: virtual __thiscall type_info::~type_info(void) +@ cdecl -i386 -norelay ??0__non_rtti_object@@QAE@ABV0@@Z(ptr) MSVCRT___non_rtti_object_copy_ctor # public: __thiscall __non_rtti_object::__non_rtti_object(class __non_rtti_object const &) +@ cdecl -i386 -norelay ??0__non_rtti_object@@QAE@PBD@Z(ptr) MSVCRT___non_rtti_object_ctor # public: __thiscall __non_rtti_object::__non_rtti_object(char const *) +@ cdecl -i386 -norelay ??0bad_cast@@AAE@PBQBD@Z(ptr) MSVCRT_bad_cast_ctor # private: __thiscall bad_cast::bad_cast(char const * const *) +@ cdecl -i386 -norelay ??0bad_cast@@QAE@ABQBD@Z(ptr) MSVCRT_bad_cast_ctor # public: __thiscall bad_cast::bad_cast(char const * const &) +@ cdecl -i386 -norelay ??0bad_cast@@QAE@ABV0@@Z(ptr) MSVCRT_bad_cast_copy_ctor # public: __thiscall bad_cast::bad_cast(class bad_cast const &) +@ cdecl -i386 -norelay ??0bad_cast@@QAE@PBD@Z(ptr) MSVCRT_bad_cast_ctor_charptr # public: __thiscall bad_cast::bad_cast(char const *) +@ cdecl -i386 -norelay ??0bad_typeid@@QAE@ABV0@@Z(ptr) MSVCRT_bad_typeid_copy_ctor # public: __thiscall bad_typeid::bad_typeid(class bad_typeid const &) +@ cdecl -i386 -norelay ??0bad_typeid@@QAE@PBD@Z(ptr) MSVCRT_bad_typeid_ctor # public: __thiscall bad_typeid::bad_typeid(char const *) +@ cdecl -i386 -norelay ??0exception@@QAE@ABQBD@Z(ptr) MSVCRT_exception_ctor # public: __thiscall exception::exception(char const * const &) +@ cdecl -i386 -norelay ??0exception@@QAE@ABQBDH@Z(ptr long) MSVCRT_exception_ctor_noalloc # public: __thiscall exception::exception(char const * const &,int) +@ cdecl -i386 -norelay ??0exception@@QAE@ABV0@@Z(ptr) MSVCRT_exception_copy_ctor # public: __thiscall exception::exception(class exception const &) +@ cdecl -i386 -norelay ??0exception@@QAE@XZ() MSVCRT_exception_default_ctor # public: __thiscall exception::exception(void) +@ cdecl -i386 -norelay ??1__non_rtti_object@@UAE@XZ() MSVCRT___non_rtti_object_dtor # public: virtual __thiscall __non_rtti_object::~__non_rtti_object(void) +@ cdecl -i386 -norelay ??1bad_cast@@UAE@XZ() MSVCRT_bad_cast_dtor # public: virtual __thiscall bad_cast::~bad_cast(void) +@ cdecl -i386 -norelay ??1bad_typeid@@UAE@XZ() MSVCRT_bad_typeid_dtor # public: virtual __thiscall bad_typeid::~bad_typeid(void) +@ cdecl -i386 -norelay ??1exception@@UAE@XZ() MSVCRT_exception_dtor # public: virtual __thiscall exception::~exception(void) +@ cdecl -i386 -norelay ??1type_info@@UAE@XZ() MSVCRT_type_info_dtor # public: virtual __thiscall type_info::~type_info(void) @ cdecl -i386 ??2@YAPAXI@Z(long) MSVCRT_operator_new # void * __cdecl operator new(unsigned int) ;@ cdecl -i386 ??2@YAPAXIHPBDH@Z(long long str long) MSVCRT_operator_new_dbg # void * __cdecl operator new(unsigned int,int,char const *,int) @ cdecl -i386 ??3@YAXPAX@Z(ptr) MSVCRT_operator_delete # void __cdecl operator delete(void *) -@ cdecl -i386 -norelay ??4__non_rtti_object@@QAEAAV0@ABV0@@Z(ptr) __thiscall_MSVCRT___non_rtti_object_opequals # public: class __non_rtti_object & __thiscall __non_rtti_object::operator=(class __non_rtti_object const &) -@ cdecl -i386 -norelay ??4bad_cast@@QAEAAV0@ABV0@@Z(ptr) __thiscall_MSVCRT_bad_cast_opequals # public: class bad_cast & __thiscall bad_cast::operator=(class bad_cast const &) -@ cdecl -i386 -norelay ??4bad_typeid@@QAEAAV0@ABV0@@Z(ptr) __thiscall_MSVCRT_bad_typeid_opequals # public: class bad_typeid & __thiscall bad_typeid::operator=(class bad_typeid const &) -@ cdecl -i386 -norelay ??4exception@@QAEAAV0@ABV0@@Z(ptr) __thiscall_MSVCRT_exception_opequals # public: class exception & __thiscall exception::operator=(class exception const &) -@ cdecl -i386 -norelay ??8type_info@@QBEHABV0@@Z(ptr) __thiscall_MSVCRT_type_info_opequals_equals # public: int __thiscall type_info::operator==(class type_info const &)const -@ cdecl -i386 -norelay ??9type_info@@QBEHABV0@@Z(ptr) __thiscall_MSVCRT_type_info_opnot_equals # public: int __thiscall type_info::operator!=(class type_info const &)const +@ cdecl -i386 -norelay ??4__non_rtti_object@@QAEAAV0@ABV0@@Z(ptr) MSVCRT___non_rtti_object_opequals # public: class __non_rtti_object & __thiscall __non_rtti_object::operator=(class __non_rtti_object const &) +@ cdecl -i386 -norelay ??4bad_cast@@QAEAAV0@ABV0@@Z(ptr) MSVCRT_bad_cast_opequals # public: class bad_cast & __thiscall bad_cast::operator=(class bad_cast const &) +@ cdecl -i386 -norelay ??4bad_typeid@@QAEAAV0@ABV0@@Z(ptr) MSVCRT_bad_typeid_opequals # public: class bad_typeid & __thiscall bad_typeid::operator=(class bad_typeid const &) +@ cdecl -i386 -norelay ??4exception@@QAEAAV0@ABV0@@Z(ptr) MSVCRT_exception_opequals # public: class exception & __thiscall exception::operator=(class exception const &) +@ cdecl -i386 -norelay ??8type_info@@QBEHABV0@@Z(ptr) MSVCRT_type_info_opequals_equals # public: int __thiscall type_info::operator==(class type_info const &)const +@ cdecl -i386 -norelay ??9type_info@@QBEHABV0@@Z(ptr) MSVCRT_type_info_opnot_equals # public: int __thiscall type_info::operator!=(class type_info const &)const @ extern -i386 ??_7__non_rtti_object@@6B@ MSVCRT___non_rtti_object_vtable # const __non_rtti_object::`vftable' @ extern -i386 ??_7bad_cast@@6B@ MSVCRT_bad_cast_vtable # const bad_cast::`vftable' @ extern -i386 ??_7bad_typeid@@6B@ MSVCRT_bad_typeid_vtable # const bad_typeid::`vftable' @ extern -i386 ??_7exception@@6B@ MSVCRT_exception_vtable # const exception::`vftable' -@ cdecl -i386 -norelay ??_E__non_rtti_object@@UAEPAXI@Z(long) __thiscall_MSVCRT___non_rtti_object_vector_dtor # public: virtual void * __thiscall __non_rtti_object::`vector deleting destructor'(unsigned int) -@ cdecl -i386 -norelay ??_Ebad_cast@@UAEPAXI@Z(long) __thiscall_MSVCRT_bad_cast_vector_dtor # public: virtual void * __thiscall bad_cast::`vector deleting destructor'(unsigned int) -@ cdecl -i386 -norelay ??_Ebad_typeid@@UAEPAXI@Z(long) __thiscall_MSVCRT_bad_typeid_vector_dtor # public: virtual void * __thiscall bad_typeid::`vector deleting destructor'(unsigned int) -@ cdecl -i386 -norelay ??_Eexception@@UAEPAXI@Z(long) __thiscall_MSVCRT_exception_vector_dtor # public: virtual void * __thiscall exception::`vector deleting destructor'(unsigned int) -@ cdecl -i386 -norelay ??_Fbad_cast@@QAEXXZ() __thiscall_MSVCRT_bad_cast_default_ctor # public: void __thiscall bad_cast::`default constructor closure'(void) -@ cdecl -i386 -norelay ??_Fbad_typeid@@QAEXXZ() __thiscall_MSVCRT_bad_typeid_default_ctor # public: void __thiscall bad_typeid::`default constructor closure'(void) -@ cdecl -i386 -norelay ??_G__non_rtti_object@@UAEPAXI@Z(long) __thiscall_MSVCRT___non_rtti_object_scalar_dtor # public: virtual void * __thiscall __non_rtti_object::`scalar deleting destructor'(unsigned int) -@ cdecl -i386 -norelay ??_Gbad_cast@@UAEPAXI@Z(long) __thiscall_MSVCRT_bad_cast_scalar_dtor # public: virtual void * __thiscall bad_cast::`scalar deleting destructor'(unsigned int) -@ cdecl -i386 -norelay ??_Gbad_typeid@@UAEPAXI@Z(long) __thiscall_MSVCRT_bad_typeid_scalar_dtor # public: virtual void * __thiscall bad_typeid::`scalar deleting destructor'(unsigned int) -@ cdecl -i386 -norelay ??_Gexception@@UAEPAXI@Z(long) __thiscall_MSVCRT_exception_scalar_dtor # public: virtual void * __thiscall exception::`scalar deleting destructor'(unsigned int) +@ cdecl -i386 -norelay ??_E__non_rtti_object@@UAEPAXI@Z(long) MSVCRT___non_rtti_object_vector_dtor # public: virtual void * __thiscall __non_rtti_object::`vector deleting destructor'(unsigned int) +@ cdecl -i386 -norelay ??_Ebad_cast@@UAEPAXI@Z(long) MSVCRT_bad_cast_vector_dtor # public: virtual void * __thiscall bad_cast::`vector deleting destructor'(unsigned int) +@ cdecl -i386 -norelay ??_Ebad_typeid@@UAEPAXI@Z(long) MSVCRT_bad_typeid_vector_dtor # public: virtual void * __thiscall bad_typeid::`vector deleting destructor'(unsigned int) +@ cdecl -i386 -norelay ??_Eexception@@UAEPAXI@Z(long) MSVCRT_exception_vector_dtor # public: virtual void * __thiscall exception::`vector deleting destructor'(unsigned int) +@ cdecl -i386 -norelay ??_Fbad_cast@@QAEXXZ() MSVCRT_bad_cast_default_ctor # public: void __thiscall bad_cast::`default constructor closure'(void) +@ cdecl -i386 -norelay ??_Fbad_typeid@@QAEXXZ() MSVCRT_bad_typeid_default_ctor # public: void __thiscall bad_typeid::`default constructor closure'(void) +@ cdecl -i386 -norelay ??_G__non_rtti_object@@UAEPAXI@Z(long) MSVCRT___non_rtti_object_scalar_dtor # public: virtual void * __thiscall __non_rtti_object::`scalar deleting destructor'(unsigned int) +@ cdecl -i386 -norelay ??_Gbad_cast@@UAEPAXI@Z(long) MSVCRT_bad_cast_scalar_dtor # public: virtual void * __thiscall bad_cast::`scalar deleting destructor'(unsigned int) +@ cdecl -i386 -norelay ??_Gbad_typeid@@UAEPAXI@Z(long) MSVCRT_bad_typeid_scalar_dtor # public: virtual void * __thiscall bad_typeid::`scalar deleting destructor'(unsigned int) +@ cdecl -i386 -norelay ??_Gexception@@UAEPAXI@Z(long) MSVCRT_exception_scalar_dtor # public: virtual void * __thiscall exception::`scalar deleting destructor'(unsigned int) @ cdecl -i386 ??_U@YAPAXI@Z(long) MSVCRT_operator_new # void * __cdecl operator new[](unsigned int) ;@ cdecl -i386 ??_U@YAPAXIHPBDH@Z(long long str long) MSVCRT_operator_new_dbg # void * __cdecl operator new[](unsigned int,int,char const *,int) @ cdecl -i386 ??_V@YAXPAX@Z(ptr) MSVCRT_operator_delete # void __cdecl operator delete[](void *) -@ cdecl -i386 -norelay __uncaught_exception(ptr) +@ cdecl -i386 -norelay __uncaught_exception(ptr) MSVCRT___uncaught_exception @ cdecl -i386 -norelay ?_query_new_handler@@YAP6AHI@ZXZ() MSVCRT__query_new_handler # int (__cdecl*__cdecl _query_new_handler(void))(unsigned int) @ cdecl -i386 ?_query_new_mode@@YAHXZ() MSVCRT__query_new_mode # int __cdecl _query_new_mode(void) @ cdecl -i386 -norelay ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z(ptr) MSVCRT__set_new_handler # int (__cdecl*__cdecl _set_new_handler(int (__cdecl*)(unsigned int)))(unsigned int) @ cdecl -i386 ?_set_new_mode@@YAHH@Z(long) MSVCRT__set_new_mode # int __cdecl _set_new_mode(int) @ cdecl -i386 -norelay ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z(ptr) MSVCRT__set_se_translator # void (__cdecl*__cdecl _set_se_translator(void (__cdecl*)(unsigned int,struct _EXCEPTION_POINTERS *)))(unsigned int,struct _EXCEPTION_POINTERS *) -@ cdecl -i386 -norelay ?before@type_info@@QBEHABV1@@Z(ptr) __thiscall_MSVCRT_type_info_before # public: int __thiscall type_info::before(class type_info const &)const -@ cdecl -i386 -norelay ?name@type_info@@QBEPBDXZ() __thiscall_MSVCRT_type_info_name # public: char const * __thiscall type_info::name(void)const -@ cdecl -i386 -norelay ?raw_name@type_info@@QBEPBDXZ() __thiscall_MSVCRT_type_info_raw_name # public: char const * __thiscall type_info::raw_name(void)const +@ cdecl -i386 -norelay ?before@type_info@@QBEHABV1@@Z(ptr) MSVCRT_type_info_before # public: int __thiscall type_info::before(class type_info const &)const +@ cdecl -i386 -norelay ?name@type_info@@QBEPBDXZ() MSVCRT_type_info_name # public: char const * __thiscall type_info::name(void)const +@ cdecl -i386 -norelay ?raw_name@type_info@@QBEPBDXZ() MSVCRT_type_info_raw_name # public: char const * __thiscall type_info::raw_name(void)const @ cdecl -i386 ?set_new_handler@@YAP6AXXZP6AXXZ@Z(ptr) MSVCRT_set_new_handler # void (__cdecl*__cdecl set_new_handler(void (__cdecl*)(void)))(void) @ cdecl -i386 ?set_terminate@@YAP6AXXZP6AXXZ@Z(ptr) MSVCRT_set_terminate # void (__cdecl*__cdecl set_terminate(void (__cdecl*)(void)))(void) @ cdecl -i386 ?set_unexpected@@YAP6AXXZP6AXXZ@Z(ptr) MSVCRT_set_unexpected # void (__cdecl*__cdecl set_unexpected(void (__cdecl*)(void)))(void) @ cdecl -i386 ?terminate@@YAXXZ() MSVCRT_terminate # void __cdecl terminate(void) @ cdecl -i386 ?unexpected@@YAXXZ() MSVCRT_unexpected # void __cdecl unexpected(void) -@ cdecl -i386 -norelay ?what@exception@@UBEPBDXZ() __thiscall_MSVCRT_what_exception # public: virtual char const * __thiscall exception::what(void)const +@ cdecl -i386 -norelay ?what@exception@@UBEPBDXZ() MSVCRT_what_exception # public: virtual char const * __thiscall exception::what(void)const
# **************** win64 C++ functions **************** @ cdecl -arch=win64 ??0__non_rtti_object@@QEAA@AEBV0@@Z(ptr) MSVCRT___non_rtti_object_copy_ctor # public: __cdecl __non_rtti_object::__non_rtti_object(class __non_rtti_object const & __ptr64) __ptr64 @@ -94,7 +94,7 @@ @ cdecl -arch=win64 ??_Fbad_typeid@@QEAAXXZ() MSVCRT_bad_typeid_default_ctor # public: void __cdecl bad_typeid::`default constructor closure'(void) __ptr64 @ cdecl -arch=win64 ??_U@YAPEAX_K@Z(long) MSVCRT_operator_new # void * __ptr64 __cdecl operator new[](unsigned __int64) @ cdecl -arch=win64 ??_V@YAXPEAX@Z(ptr) MSVCRT_operator_delete # void __cdecl operator delete[](void * __ptr64) -@ cdecl -arch=win64 __uncaught_exception(ptr) +@ cdecl -arch=win64 __uncaught_exception(ptr) MSVCRT___uncaught_exception @ cdecl -arch=win64 ?_query_new_handler@@YAP6AH_K@ZXZ() MSVCRT__query_new_handler # int (__cdecl*__cdecl _query_new_handler(void))(unsigned __int64) @ cdecl -arch=win64 ?_query_new_mode@@YAHXZ() MSVCRT__query_new_mode # int __cdecl _query_new_mode(void) @ cdecl -arch=win64 ?_set_new_handler@@YAP6AH_K@ZP6AH0@Z@Z(ptr) MSVCRT__set_new_handler # int (__cdecl*__cdecl _set_new_handler(int (__cdecl*)(unsigned __int64)))(unsigned __int64) @@ -108,7 +108,7 @@ @ cdecl -arch=win64 ?set_unexpected@@YAP6AXXZP6AXXZ@Z(ptr) MSVCRT_set_unexpected # void (__cdecl*__cdecl set_unexpected(void (__cdecl*)(void)))(void) @ cdecl -arch=win64 ?terminate@@YAXXZ() MSVCRT_terminate # void __cdecl terminate(void) @ cdecl -arch=win64 ?unexpected@@YAXXZ() MSVCRT_unexpected # void __cdecl unexpected(void) -@ cdecl -arch=win64 -stub ?what@exception@@UEBAPEBDXZ() MSVCRT_what_exception # public: virtual char const * __ptr64 __cdecl exception::what(void)const __ptr64 +@ cdecl -arch=win64 ?what@exception@@UEBAPEBDXZ() MSVCRT_what_exception # public: virtual char const * __ptr64 __cdecl exception::what(void)const __ptr64
# **************** ARM C++ functions **************** @ cdecl -arch=arm ??0__non_rtti_object@@QAA@ABV0@@Z() MSVCRT___non_rtti_object_copy_ctor # public: __cdecl __non_rtti_object::__non_rtti_object(class __non_rtti_object const &) @@ -204,14 +204,14 @@ # stub __CxxCallUnwindDtor # stub __CxxCallUnwindVecDtor @ cdecl __CxxDetectRethrow(ptr) -# stub __CxxExceptionFilter +@ cdecl __CxxExceptionFilter() @ cdecl -arch=i386,x86_64 -norelay __CxxFrameHandler(ptr ptr ptr ptr) @ cdecl -arch=i386 -norelay __CxxFrameHandler2(ptr ptr ptr ptr) __CxxFrameHandler @ cdecl -arch=arm -norelay __CxxFrameHandler3(ptr ptr ptr ptr) @ stdcall -i386 __CxxLongjmpUnwind(ptr) @ cdecl -i386 __CxxQueryExceptionSize() -# stub -i386 __CxxRegisterExceptionObject -# stub -i386 __CxxUnregisterExceptionObject +@ cdecl -i386 __CxxRegisterExceptionObject() +@ cdecl -i386 __CxxUnregisterExceptionObject() @ cdecl -version=0x600+ __DestructExceptionObject(ptr) @ cdecl __RTCastToVoid(ptr) MSVCRT___RTCastToVoid @ cdecl __RTDynamicCast(ptr long ptr ptr long) MSVCRT___RTDynamicCast @@ -329,7 +329,7 @@ @ cdecl _callnewh(long) @ cdecl _cexit() @ cdecl _cgets(str) -# stub _cgetws +@ cdecl -stub _cgetws(wstr) @ cdecl _chdir(str) @ cdecl _chdrive(long) @ cdecl _chgsign(double) @@ -347,14 +347,14 @@ @ cdecl -arch=x86_64,arm _copysignf(long long) @ varargs _cprintf(str) @ cdecl _cputs(str) -# stub _cputws +@ cdecl -stub _cputws(wstr) @ cdecl _creat(str long) @ varargs _cscanf(str) @ cdecl _ctime64(ptr) @ extern _ctype @ cdecl _cwait(ptr long long) @ varargs _cwprintf(wstr) -# @ varargs _cwscanf(wstr) +@ varargs -stub _cwscanf(wstr) @ extern _daylight @ extern _dstbias @ cdecl _dup(long) @@ -431,8 +431,8 @@ @ cdecl _getpid() kernel32.GetCurrentProcessId @ cdecl _getsystime(ptr) @ cdecl _getw(ptr) -# stub _getwch -# stub _getwche +@ cdecl -stub _getwch() +@ cdecl -stub _getwche() @ cdecl _getws(ptr) @ cdecl -i386 _global_unwind2(ptr) @ cdecl _gmtime64(ptr) diff --git a/dll/win32/msvcrt40/msvcrt40.spec b/dll/win32/msvcrt40/msvcrt40.spec index fab52fec803..d1efd557b46 100644 --- a/dll/win32/msvcrt40/msvcrt40.spec +++ b/dll/win32/msvcrt40/msvcrt40.spec @@ -1,14 +1,14 @@ @ stub ??0Iostream_init@@QAE@AAVios@@H@Z @ stub ??0Iostream_init@@QAE@XZ -@ cdecl -i386 ??0__non_rtti_object@@QAE@ABV0@@Z(ptr) __thiscall_MSVCRT___non_rtti_object_copy_ctor -@ cdecl -i386 ??0__non_rtti_object@@QAE@PBD@Z(ptr) __thiscall_MSVCRT___non_rtti_object_ctor -@ cdecl -i386 ??0bad_cast@@QAE@ABQBD@Z(ptr) __thiscall_MSVCRT_bad_cast_ctor -@ cdecl -i386 ??0bad_cast@@QAE@ABV0@@Z(ptr) __thiscall_MSVCRT_bad_cast_copy_ctor -@ cdecl -i386 ??0bad_typeid@@QAE@ABV0@@Z(ptr) __thiscall_MSVCRT_bad_typeid_copy_ctor -@ cdecl -i386 ??0bad_typeid@@QAE@PBD@Z(ptr) __thiscall_MSVCRT_bad_typeid_ctor -@ cdecl -i386 ??0exception@@QAE@ABQBD@Z(ptr) __thiscall_MSVCRT_exception_ctor -@ cdecl -i386 ??0exception@@QAE@ABV0@@Z(ptr) __thiscall_MSVCRT_exception_copy_ctor -@ cdecl -i386 ??0exception@@QAE@XZ() __thiscall_MSVCRT_exception_default_ctor +@ cdecl -i386 ??0__non_rtti_object@@QAE@ABV0@@Z(ptr) MSVCRT___non_rtti_object_copy_ctor +@ cdecl -i386 ??0__non_rtti_object@@QAE@PBD@Z(ptr) MSVCRT___non_rtti_object_ctor +@ cdecl -i386 ??0bad_cast@@QAE@ABQBD@Z(ptr) MSVCRT_bad_cast_ctor +@ cdecl -i386 ??0bad_cast@@QAE@ABV0@@Z(ptr) MSVCRT_bad_cast_copy_ctor +@ cdecl -i386 ??0bad_typeid@@QAE@ABV0@@Z(ptr) MSVCRT_bad_typeid_copy_ctor +@ cdecl -i386 ??0bad_typeid@@QAE@PBD@Z(ptr) MSVCRT_bad_typeid_ctor +@ cdecl -i386 ??0exception@@QAE@ABQBD@Z(ptr) MSVCRT_exception_ctor +@ cdecl -i386 ??0exception@@QAE@ABV0@@Z(ptr) MSVCRT_exception_copy_ctor +@ cdecl -i386 ??0exception@@QAE@XZ() MSVCRT_exception_default_ctor @ stub ??0filebuf@@QAE@ABV0@@Z @ stub ??0filebuf@@QAE@H@Z @ stub ??0filebuf@@QAE@HPADH@Z @@ -70,10 +70,10 @@ @ stub ??0strstreambuf@@QAE@PADH0@Z @ stub ??0strstreambuf@@QAE@XZ @ stub ??1Iostream_init@@QAE@XZ -@ cdecl -i386 ??1__non_rtti_object@@UAE@XZ() __thiscall_MSVCRT___non_rtti_object_dtor -@ cdecl -i386 ??1bad_cast@@UAE@XZ() __thiscall_MSVCRT_bad_cast_dtor -@ cdecl -i386 ??1bad_typeid@@UAE@XZ() __thiscall_MSVCRT_bad_typeid_dtor -@ cdecl -i386 ??1exception@@UAE@XZ() __thiscall_MSVCRT_exception_dtor +@ cdecl -i386 ??1__non_rtti_object@@UAE@XZ() MSVCRT___non_rtti_object_dtor +@ cdecl -i386 ??1bad_cast@@UAE@XZ() MSVCRT_bad_cast_dtor +@ cdecl -i386 ??1bad_typeid@@UAE@XZ() MSVCRT_bad_typeid_dtor +@ cdecl -i386 ??1exception@@UAE@XZ() MSVCRT_exception_dtor @ stub ??1filebuf@@UAE@XZ @ stub ??1fstream@@UAE@XZ @ stub ??1ifstream@@UAE@XZ @@ -92,16 +92,16 @@ @ stub ??1streambuf@@UAE@XZ @ stub ??1strstream@@UAE@XZ @ stub ??1strstreambuf@@UAE@XZ -@ cdecl -i386 ??1type_info@@UAE@XZ() __thiscall_MSVCRT_type_info_dtor +@ cdecl -i386 ??1type_info@@UAE@XZ() MSVCRT_type_info_dtor @ cdecl -arch=win32 ??2@YAPAXI@Z(long) MSVCRT_operator_new @ cdecl -arch=win64 ??2@YAPEAX_K@Z(double) MSVCRT_operator_new @ cdecl -arch=win32 ??3@YAXPAX@Z(ptr) MSVCRT_operator_delete @ cdecl -arch=win64 ??3@YAXPEAX@Z(ptr) MSVCRT_operator_delete @ stub ??4Iostream_init@@QAEAAV0@ABV0@@Z -@ cdecl -i386 ??4__non_rtti_object@@QAEAAV0@ABV0@@Z(ptr) __thiscall_MSVCRT___non_rtti_object_opequals -@ cdecl -i386 ??4bad_cast@@QAEAAV0@ABV0@@Z(ptr) __thiscall_MSVCRT_bad_cast_opequals -@ cdecl -i386 ??4bad_typeid@@QAEAAV0@ABV0@@Z(ptr) __thiscall_MSVCRT_bad_typeid_opequals -@ cdecl -i386 ??4exception@@QAEAAV0@ABV0@@Z(ptr) __thiscall_MSVCRT_exception_opequals +@ cdecl -i386 ??4__non_rtti_object@@QAEAAV0@ABV0@@Z(ptr) MSVCRT___non_rtti_object_opequals +@ cdecl -i386 ??4bad_cast@@QAEAAV0@ABV0@@Z(ptr) MSVCRT_bad_cast_opequals +@ cdecl -i386 ??4bad_typeid@@QAEAAV0@ABV0@@Z(ptr) MSVCRT_bad_typeid_opequals +@ cdecl -i386 ??4exception@@QAEAAV0@ABV0@@Z(ptr) MSVCRT_exception_opequals @ stub ??4filebuf@@QAEAAV0@ABV0@@Z @ stub ??4fstream@@QAEAAV0@AAV0@@Z @ stub ??4ifstream@@QAEAAV0@ABV0@@Z @@ -165,8 +165,8 @@ @ stub ??6ostream@@QAEAAV0@PBE@Z @ stub ??6ostream@@QAEAAV0@PBX@Z @ stub ??7ios@@QBEHXZ -@ cdecl -i386 ??8type_info@@QBEHABV0@@Z(ptr) __thiscall_MSVCRT_type_info_opequals_equals -@ cdecl -i386 ??9type_info@@QBEHABV0@@Z(ptr) __thiscall_MSVCRT_type_info_opnot_equals +@ cdecl -i386 ??8type_info@@QBEHABV0@@Z(ptr) MSVCRT_type_info_opequals_equals +@ cdecl -i386 ??9type_info@@QBEHABV0@@Z(ptr) MSVCRT_type_info_opnot_equals @ stub ??Bios@@QBEPAXXZ @ extern -i386 ??_7__non_rtti_object@@6B@ MSVCRT___non_rtti_object_vtable @ extern -i386 ??_7bad_cast@@6B@ MSVCRT_bad_cast_vtable @@ -219,10 +219,10 @@ @ stub ??_Dstdiostream@@QAEXXZ @ stub ??_Dstrstream@@QAEXXZ @ stub ??_EIostream_init@@QAEPAXI@Z -@ cdecl -i386 ??_E__non_rtti_object@@UAEPAXI@Z(long) __thiscall_MSVCRT___non_rtti_object_vector_dtor -@ cdecl -i386 ??_Ebad_cast@@UAEPAXI@Z(long) __thiscall_MSVCRT_bad_cast_vector_dtor -@ cdecl -i386 ??_Ebad_typeid@@UAEPAXI@Z(long) __thiscall_MSVCRT_bad_typeid_vector_dtor -@ cdecl -i386 ??_Eexception@@UAEPAXI@Z(long) __thiscall_MSVCRT_exception_vector_dtor +@ cdecl -i386 ??_E__non_rtti_object@@UAEPAXI@Z(long) MSVCRT___non_rtti_object_vector_dtor +@ cdecl -i386 ??_Ebad_cast@@UAEPAXI@Z(long) MSVCRT_bad_cast_vector_dtor +@ cdecl -i386 ??_Ebad_typeid@@UAEPAXI@Z(long) MSVCRT_bad_typeid_vector_dtor +@ cdecl -i386 ??_Eexception@@UAEPAXI@Z(long) MSVCRT_exception_vector_dtor @ stub ??_Efilebuf@@UAEPAXI@Z @ stub ??_Efstream@@UAEPAXI@Z @ stub ??_Eifstream@@UAEPAXI@Z @@ -242,10 +242,10 @@ @ stub ??_Estrstream@@UAEPAXI@Z @ stub ??_Estrstreambuf@@UAEPAXI@Z @ stub ??_GIostream_init@@QAEPAXI@Z -@ cdecl -i386 ??_G__non_rtti_object@@UAEPAXI@Z(long) __thiscall_MSVCRT___non_rtti_object_scalar_dtor -@ cdecl -i386 ??_Gbad_cast@@UAEPAXI@Z(long) __thiscall_MSVCRT_bad_cast_scalar_dtor -@ cdecl -i386 ??_Gbad_typeid@@UAEPAXI@Z(long) __thiscall_MSVCRT_bad_typeid_scalar_dtor -@ cdecl -i386 ??_Gexception@@UAEPAXI@Z(long) __thiscall_MSVCRT_exception_scalar_dtor +@ cdecl -i386 ??_G__non_rtti_object@@UAEPAXI@Z(long) MSVCRT___non_rtti_object_scalar_dtor +@ cdecl -i386 ??_Gbad_cast@@UAEPAXI@Z(long) MSVCRT_bad_cast_scalar_dtor +@ cdecl -i386 ??_Gbad_typeid@@UAEPAXI@Z(long) MSVCRT_bad_typeid_scalar_dtor +@ cdecl -i386 ??_Gexception@@UAEPAXI@Z(long) MSVCRT_exception_scalar_dtor @ stub ??_Gfilebuf@@UAEPAXI@Z @ stub ??_Gfstream@@UAEPAXI@Z @ stub ??_Gifstream@@UAEPAXI@Z @@ -278,7 +278,7 @@ @ stub ?bad@ios@@QBEHXZ @ stub ?base@streambuf@@IBEPADXZ @ stub ?basefield@ios@@2JB -@ cdecl -i386 ?before@type_info@@QBEHABV1@@Z(ptr) __thiscall_MSVCRT_type_info_before +@ cdecl -i386 ?before@type_info@@QBEHABV1@@Z(ptr) MSVCRT_type_info_before @ stub ?binary@filebuf@@2HB @ stub ?bitalloc@ios@@SAJXZ @ stub ?blen@streambuf@@IBEHXZ @@ -356,7 +356,7 @@ @ stub ?lockc@ios@@KAXXZ @ stub ?lockptr@ios@@IAEPAU_CRT_CRITICAL_SECTION@@XZ @ stub ?lockptr@streambuf@@IAEPAU_CRT_CRITICAL_SECTION@@XZ -@ cdecl -i386 ?name@type_info@@QBEPBDXZ() __thiscall_MSVCRT_type_info_name +@ cdecl -i386 ?name@type_info@@QBEPBDXZ() MSVCRT_type_info_name @ stub ?oct@@YAAAVios@@AAV1@@Z @ stub ?open@filebuf@@QAEPAV1@PBDHH@Z @ stub ?open@fstream@@QAEXPBDHH@Z @@ -384,7 +384,7 @@ @ stub ?put@ostream@@QAEAAV1@E@Z @ stub ?putback@istream@@QAEAAV1@D@Z @ stub ?pword@ios@@QBEAAPAXH@Z -@ cdecl -i386 ?raw_name@type_info@@QBEPBDXZ() __thiscall_MSVCRT_type_info_raw_name +@ cdecl -i386 ?raw_name@type_info@@QBEPBDXZ() MSVCRT_type_info_raw_name @ stub ?rdbuf@fstream@@QBEPAVfilebuf@@XZ @ stub ?rdbuf@ifstream@@QBEPAVfilebuf@@XZ @ stub ?rdbuf@ios@@QBEPAVstreambuf@@XZ @@ -467,7 +467,7 @@ @ stub ?unlockbuf@ios@@QAAXXZ @ stub ?unlockc@ios@@KAXXZ @ stub ?unsetf@ios@@QAEJJ@Z -@ cdecl -i386 ?what@exception@@UBEPBDXZ() __thiscall_MSVCRT_what_exception +@ cdecl -i386 ?what@exception@@UBEPBDXZ() MSVCRT_what_exception @ stub ?width@ios@@QAEHH@Z @ stub ?width@ios@@QBEHXZ @ stub ?write@ostream@@QAEAAV1@PBCH@Z diff --git a/sdk/include/reactos/wine/asm.h b/sdk/include/reactos/wine/asm.h index 41a5de32026..14406b784eb 100644 --- a/sdk/include/reactos/wine/asm.h +++ b/sdk/include/reactos/wine/asm.h @@ -99,6 +99,10 @@
/* thiscall support */
+#ifdef _MSC_VER +#define __thiscall __stdcall +#endif + #if defined(__i386__) && !defined(__MINGW32__)
# ifdef _MSC_VER diff --git a/sdk/include/reactos/wine/config.h b/sdk/include/reactos/wine/config.h index 670320898e4..7fd05d526e3 100644 --- a/sdk/include/reactos/wine/config.h +++ b/sdk/include/reactos/wine/config.h @@ -1316,43 +1316,6 @@ /* Define for large files, on AIX-style hosts. */ /* #undef _LARGE_FILES */
-/* Define to a macro to output a .cfi assembly pseudo-op */ -#define __ASM_CFI(str) str - -/* Define to a macro to define an assembly function */ -#ifndef _MSC_VER -#ifndef NO_UNDERSCORE_PREFIX -#define __ASM_DEFINE_FUNC(name,suffix,code) asm(".text\n\t.align 4\n\t.globl _" #name suffix "\n\t.def _" #name suffix "; .scl 2; .type 32; .endef\n_" #name suffix ":\n\t.cfi_startproc\n\t" code "\n\t.cfi_endproc"); -#else -#define __ASM_DEFINE_FUNC(name,suffix,code) asm(".text\n\t.align 4\n\t.globl " #name suffix "\n\t.def " #name suffix "; .scl 2; .type 32; .endef\n" #name suffix ":\n\t.cfi_startproc\n\t" code "\n\t.cfi_endproc"); -#endif -#else -#define __ASM_DEFINE_FUNC(name,suffix,code) -#endif - -/* Define to a macro to generate an assembly function directive */ -#define __ASM_FUNC(name) ".def " __ASM_NAME(name) "; .scl 2; .type 32; .endef" - -/* Define to a macro to generate an assembly function with C calling - convention */ -#define __ASM_GLOBAL_FUNC(name,code) __ASM_DEFINE_FUNC(name,"",code) - -/* Define to a macro to generate an assembly name from a C symbol */ -#ifndef NO_UNDERSCORE_PREFIX -#define __ASM_NAME(name) "_" name -#else -#define __ASM_NAME(name) name -#endif - -/* Define to a macro to generate an stdcall suffix */ -#define __ASM_STDCALL(args) "@" #args - -/* Define to a macro to generate an assembly function with stdcall calling - convention */ -#ifndef _MSC_VER -#define __ASM_STDCALL_FUNC(name,args,code) __ASM_DEFINE_FUNC(name,__ASM_STDCALL(args),code) -#endif - /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */
diff --git a/sdk/include/reactos/wine/exception.h b/sdk/include/reactos/wine/exception.h index b16d502f826..9b29f2e470f 100644 --- a/sdk/include/reactos/wine/exception.h +++ b/sdk/include/reactos/wine/exception.h @@ -16,6 +16,8 @@ extern "C" { #define EH_EXIT_UNWIND 0x04 #define EH_STACK_INVALID 0x08 #define EH_NESTED_CALL 0x10 +#define EH_TARGET_UNWIND 0x20 +#define EH_COLLIDED_UNWIND 0x40
#define EXCEPTION_WINE_STUB 0x80000100 #define EXCEPTION_WINE_ASSERTION 0x80000101 @@ -56,6 +58,7 @@ typedef struct _WINE_EXCEPTION_REGISTRATION_RECORD
#define __TRY _SEH2_TRY #define __EXCEPT(func) _SEH2_EXCEPT(func(_SEH2_GetExceptionInformation())) +#define __EXCEPT_CTX(func, ctx) _SEH2_EXCEPT((func)(GetExceptionInformation(), ctx)) #define __EXCEPT_PAGE_FAULT _SEH2_EXCEPT(_SEH2_GetExceptionCode() == STATUS_ACCESS_VIOLATION) #define __EXCEPT_ALL _SEH2_EXCEPT(_SEH_EXECUTE_HANDLER) #define __ENDTRY _SEH2_END diff --git a/sdk/lib/crt/crt.cmake b/sdk/lib/crt/crt.cmake index 144a6000976..91f186013b6 100644 --- a/sdk/lib/crt/crt.cmake +++ b/sdk/lib/crt/crt.cmake @@ -20,12 +20,8 @@ list(APPEND CRT_SOURCE direct/wgetdcwd.c direct/wmkdir.c direct/wrmdir.c - except/cpp.c - except/cppexcept.c - except/except.c except/matherr.c except/stack.c - except/xcptfil.c float/chgsign.c float/copysign.c float/fpclass.c @@ -360,7 +356,11 @@ list(APPEND CRT_SOURCE wstring/wcsstr.c wstring/wcstok.c wstring/wcsupr.c - wstring/wcsxfrm.c + wstring/wcsxfrm.c) + +list(APPEND CRT_WINE_SOURCE + wine/cpp.c + wine/except.c wine/heap.c wine/undname.c)
@@ -424,7 +424,6 @@ if(ARCH STREQUAL "i386") string/i386/wcsrchr_asm.s)
list(APPEND CRT_SOURCE - except/i386/unwind.c float/i386/clearfp.c float/i386/cntrlfp.c float/i386/fpreset.c @@ -437,6 +436,8 @@ if(ARCH STREQUAL "i386") math/i386/cisin.c math/i386/cisqrt.c math/i386/ldexp.c) + list(APPEND CRT_WINE_SOURCE + wine/except_i386.c) if(MSVC) list(APPEND CRT_ASM_SOURCE except/i386/cpp.s) @@ -477,6 +478,8 @@ elseif(ARCH STREQUAL "amd64") except/amd64/ehandler.c float/i386/cntrlfp.c float/i386/statfp.c) + list(APPEND CRT_WINE_SOURCE + wine/except_x86_64.c) if(MSVC) list(APPEND CRT_ASM_SOURCE except/amd64/cpp.s) @@ -491,6 +494,9 @@ elseif(ARCH STREQUAL "arm") math/arm/__rt_udiv.c math/arm/__rt_udiv64_worker.c ) + list(APPEND CRT_WINE_SOURCE + wine/except_arm.c + ) list(APPEND CRT_ASM_SOURCE except/arm/_abnormal_termination.s except/arm/_except_handler2.s @@ -584,6 +590,9 @@ if(NOT ARCH STREQUAL "i386") string/wcsrchr.c) endif()
+# includes for wine code +include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) + set_source_files_properties(${CRT_ASM_SOURCE} PROPERTIES COMPILE_DEFINITIONS "__MINGW_IMPORT=extern;USE_MSVCRT_PREFIX;_MSVCRT_LIB_;_MSVCRT_;_MT;CRTDLL") add_asm_files(crt_asm ${CRT_ASM_SOURCE})
@@ -593,7 +602,7 @@ if(USE_CLANG_CL) set_property(SOURCE stdlib/rot.c APPEND_STRING PROPERTY COMPILE_FLAGS " /fallback") endif()
-add_library(crt ${CRT_SOURCE} ${crt_asm}) +add_library(crt ${CRT_SOURCE} ${CRT_WINE_SOURCE} ${crt_asm}) target_link_libraries(crt chkstk) add_target_compile_definitions(crt __MINGW_IMPORT=extern diff --git a/sdk/lib/crt/except/amd64/ehandler.c b/sdk/lib/crt/except/amd64/ehandler.c index 3705e4a7ed7..6e28e78e604 100644 --- a/sdk/lib/crt/except/amd64/ehandler.c +++ b/sdk/lib/crt/except/amd64/ehandler.c @@ -16,15 +16,7 @@ __C_specific_handler( return 0; }
-DWORD -__CxxFrameHandler( - PEXCEPTION_RECORD rec, - EXCEPTION_REGISTRATION_RECORD* ExceptionRegistrationFrame, - PCONTEXT context, - EXCEPTION_REGISTRATION_RECORD** _ExceptionRecord) +void __cdecl _local_unwind(void* frame, void* target) { - UNIMPLEMENTED; - __debugbreak(); - return 0; + RtlUnwind(frame, target, NULL, 0); } - diff --git a/sdk/lib/crt/except/amd64/seh.s b/sdk/lib/crt/except/amd64/seh.s index 06bd671721d..77d0f368e4d 100644 --- a/sdk/lib/crt/except/amd64/seh.s +++ b/sdk/lib/crt/except/amd64/seh.s @@ -18,7 +18,6 @@ /* GLOBALS *******************************************************************/
PUBLIC _global_unwind2 -PUBLIC _local_unwind PUBLIC _local_unwind2 PUBLIC _abnormal_termination PUBLIC _except_handler2 @@ -42,11 +41,6 @@ FUNC _abnormal_termination ret ENDFUNC
-FUNC _local_unwind - .endprolog - ret -ENDFUNC - FUNC _local_unwind2 .endprolog ret diff --git a/sdk/lib/crt/except/cpp.c b/sdk/lib/crt/except/cpp.c deleted file mode 100644 index 67fd29674d2..00000000000 --- a/sdk/lib/crt/except/cpp.c +++ /dev/null @@ -1,1266 +0,0 @@ -/* - * msvcrt.dll C++ objects - * - * Copyright 2000 Jon Griffiths - * Copyright 2003, 2004 Alexandre Julliard - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include <precomp.h> - -#include <wine/exception.h> -#include <internal/wine/msvcrt.h> -#include <internal/wine/cppexcept.h> - -typedef exception bad_cast; -typedef exception bad_typeid; -typedef exception __non_rtti_object; - -typedef struct _rtti_base_descriptor -{ - const type_info *type_descriptor; - int num_base_classes; - this_ptr_offsets offsets; /* offsets for computing the this pointer */ - unsigned int attributes; -} rtti_base_descriptor; - -typedef struct _rtti_base_array -{ - const rtti_base_descriptor *bases[3]; /* First element is the class itself */ -} rtti_base_array; - -typedef struct _rtti_object_hierarchy -{ - unsigned int signature; - unsigned int attributes; - int array_len; /* Size of the array pointed to by 'base_classes' */ - const rtti_base_array *base_classes; -} rtti_object_hierarchy; - -typedef struct _rtti_object_locator -{ - unsigned int signature; - int base_class_offset; - unsigned int flags; - const type_info *type_descriptor; - const rtti_object_hierarchy *type_hierarchy; -} rtti_object_locator; - -#ifdef __i386__ /* thiscall functions are i386-specific */ - -#define THISCALL(func) __thiscall_ ## func -#define THISCALL_NAME(func) __ASM_NAME("__thiscall_" #func) - -#ifdef _MSC_VER -#include <internal/wine_msc.h> -#else -#define DEFINE_THISCALL_WRAPPER(func,args) \ - extern void THISCALL(func)(void); \ - __ASM_GLOBAL_FUNC(__thiscall_ ## func, \ - "popl %eax\n\t" \ - "pushl %ecx\n\t" \ - "pushl %eax\n\t" \ - "jmp " __ASM_NAME(#func) __ASM_STDCALL(args) ) -#endif /* _MSC_VER */ - -#else /* __i386__ */ - -#define THISCALL(func) func -#define THISCALL_NAME(func) __ASM_NAME(#func) -#define DEFINE_THISCALL_WRAPPER(func,args) /* nothing */ - -#endif /* __i386__ */ - -extern const vtable_ptr MSVCRT_exception_vtable; -extern const vtable_ptr MSVCRT_bad_typeid_vtable; -extern const vtable_ptr MSVCRT_bad_cast_vtable; -extern const vtable_ptr MSVCRT___non_rtti_object_vtable; -extern const vtable_ptr MSVCRT_type_info_vtable; - -/* get the vtable pointer for a C++ object */ -static inline const vtable_ptr *get_vtable( void *obj ) -{ - return *(const vtable_ptr **)obj; -} - -static inline const rtti_object_locator *get_obj_locator( void *cppobj ) -{ - const vtable_ptr *vtable = get_vtable( cppobj ); - return (const rtti_object_locator *)vtable[-1]; -} - -static void dump_obj_locator( const rtti_object_locator *ptr ) -{ - int i; - const rtti_object_hierarchy *h = ptr->type_hierarchy; - - TRACE( "%p: sig=%08x base_offset=%08x flags=%08x type=%p %s hierarchy=%p\n", - ptr, ptr->signature, ptr->base_class_offset, ptr->flags, - ptr->type_descriptor, dbgstr_type_info(ptr->type_descriptor), ptr->type_hierarchy ); - TRACE( " hierarchy: sig=%08x attr=%08x len=%d base classes=%p\n", - h->signature, h->attributes, h->array_len, h->base_classes ); - for (i = 0; i < h->array_len; i++) - { - TRACE( " base class %p: num %d off %d,%d,%d attr %08x type %p %s\n", - h->base_classes->bases[i], - h->base_classes->bases[i]->num_base_classes, - h->base_classes->bases[i]->offsets.this_offset, - h->base_classes->bases[i]->offsets.vbase_descr, - h->base_classes->bases[i]->offsets.vbase_offset, - h->base_classes->bases[i]->attributes, - h->base_classes->bases[i]->type_descriptor, - dbgstr_type_info(h->base_classes->bases[i]->type_descriptor) ); - } -} - -/* Internal common ctor for exception */ -static void EXCEPTION_ctor(exception *_this, const char** name) -{ - _this->vtable = &MSVCRT_exception_vtable; - if (*name) - { - size_t name_len = strlen(*name) + 1; - _this->name = MSVCRT_malloc(name_len); - memcpy(_this->name, *name, name_len); - _this->do_free = TRUE; - } - else - { - _this->name = NULL; - _this->do_free = FALSE; - } -} - -/****************************************************************** - * ??0exception@@QAE@ABQBD@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_exception_ctor,8) -exception * __stdcall MSVCRT_exception_ctor(exception * _this, const char ** name) -{ - TRACE("(%p,%s)\n", _this, *name); - EXCEPTION_ctor(_this, name); - return _this; -} - -/****************************************************************** - * ??0exception@@QAE@ABQBDH@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_exception_ctor_noalloc,12) -exception * __stdcall MSVCRT_exception_ctor_noalloc(exception * _this, char ** name, int noalloc) -{ - TRACE("(%p,%s)\n", _this, *name); - _this->vtable = &MSVCRT_exception_vtable; - _this->name = *name; - _this->do_free = FALSE; - return _this; -} - -/****************************************************************** - * ??0exception@@QAE@ABV0@@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_exception_copy_ctor,8) -exception * __stdcall MSVCRT_exception_copy_ctor(exception * _this, const exception * rhs) -{ - TRACE("(%p,%p)\n", _this, rhs); - - if (!rhs->do_free) - { - _this->vtable = &MSVCRT_exception_vtable; - _this->name = rhs->name; - _this->do_free = FALSE; - } - else - EXCEPTION_ctor(_this, (const char**)&rhs->name); - TRACE("name = %s\n", _this->name); - return _this; -} - -/****************************************************************** - * ??0exception@@QAE@XZ (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_exception_default_ctor,4) -exception * __stdcall MSVCRT_exception_default_ctor(exception * _this) -{ - static const char* empty = NULL; - - TRACE("(%p)\n", _this); - EXCEPTION_ctor(_this, &empty); - return _this; -} - -/****************************************************************** - * ??1exception@@UAE@XZ (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_exception_dtor,4) -void __stdcall MSVCRT_exception_dtor(exception * _this) -{ - TRACE("(%p)\n", _this); - _this->vtable = &MSVCRT_exception_vtable; - if (_this->do_free) MSVCRT_free(_this->name); -} - -/****************************************************************** - * ??4exception@@QAEAAV0@ABV0@@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_exception_opequals,8) -exception * __stdcall MSVCRT_exception_opequals(exception * _this, const exception * rhs) -{ - TRACE("(%p %p)\n", _this, rhs); - if (_this != rhs) - { - MSVCRT_exception_dtor(_this); - MSVCRT_exception_copy_ctor(_this, rhs); - } - TRACE("name = %s\n", _this->name); - return _this; -} - -/****************************************************************** - * ??_Eexception@@UAEPAXI@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_exception_vector_dtor,8) -void * __stdcall MSVCRT_exception_vector_dtor(exception * _this, unsigned int flags) -{ - TRACE("(%p %x)\n", _this, flags); - if (flags & 2) - { - /* we have an array, with the number of elements stored before the first object */ - int i, *ptr = (int *)_this - 1; - - for (i = *ptr - 1; i >= 0; i--) MSVCRT_exception_dtor(_this + i); - MSVCRT_operator_delete(ptr); - } - else - { - MSVCRT_exception_dtor(_this); - if (flags & 1) MSVCRT_operator_delete(_this); - } - return _this; -} - -/****************************************************************** - * ??_Gexception@@UAEPAXI@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_exception_scalar_dtor,8) -void * __stdcall MSVCRT_exception_scalar_dtor(exception * _this, unsigned int flags) -{ - TRACE("(%p %x)\n", _this, flags); - MSVCRT_exception_dtor(_this); - if (flags & 1) MSVCRT_operator_delete(_this); - return _this; -} - -/****************************************************************** - * ?what@exception@@UBEPBDXZ (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_what_exception,4) -const char * __stdcall MSVCRT_what_exception(exception * _this) -{ - TRACE("(%p) returning %s\n", _this, _this->name); - return _this->name ? _this->name : "Unknown exception"; -} - -/****************************************************************** - * ??0bad_typeid@@QAE@ABV0@@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_copy_ctor,8) -bad_typeid * __stdcall MSVCRT_bad_typeid_copy_ctor(bad_typeid * _this, const bad_typeid * rhs) -{ - TRACE("(%p %p)\n", _this, rhs); - MSVCRT_exception_copy_ctor(_this, rhs); - _this->vtable = &MSVCRT_bad_typeid_vtable; - return _this; -} - -/****************************************************************** - * ??0bad_typeid@@QAE@PBD@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_ctor,8) -bad_typeid * __stdcall MSVCRT_bad_typeid_ctor(bad_typeid * _this, const char * name) -{ - TRACE("(%p %s)\n", _this, name); - EXCEPTION_ctor(_this, &name); - _this->vtable = &MSVCRT_bad_typeid_vtable; - return _this; -} - -/****************************************************************** - * ??_Fbad_typeid@@QAEXXZ (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_default_ctor,4) -bad_typeid * __stdcall MSVCRT_bad_typeid_default_ctor(bad_typeid * _this) -{ - return MSVCRT_bad_typeid_ctor( _this, "bad typeid" ); -} - -/****************************************************************** - * ??1bad_typeid@@UAE@XZ (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_dtor,4) -void __stdcall MSVCRT_bad_typeid_dtor(bad_typeid * _this) -{ - TRACE("(%p)\n", _this); - MSVCRT_exception_dtor(_this); -} - -/****************************************************************** - * ??4bad_typeid@@QAEAAV0@ABV0@@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_opequals,8) -bad_typeid * __stdcall MSVCRT_bad_typeid_opequals(bad_typeid * _this, const bad_typeid * rhs) -{ - TRACE("(%p %p)\n", _this, rhs); - MSVCRT_exception_opequals(_this, rhs); - return _this; -} - -/****************************************************************** - * ??_Ebad_typeid@@UAEPAXI@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_vector_dtor,8) -void * __stdcall MSVCRT_bad_typeid_vector_dtor(bad_typeid * _this, unsigned int flags) -{ - TRACE("(%p %x)\n", _this, flags); - if (flags & 2) - { - /* we have an array, with the number of elements stored before the first object */ - int i, *ptr = (int *)_this - 1; - - for (i = *ptr - 1; i >= 0; i--) MSVCRT_bad_typeid_dtor(_this + i); - MSVCRT_operator_delete(ptr); - } - else - { - MSVCRT_bad_typeid_dtor(_this); - if (flags & 1) MSVCRT_operator_delete(_this); - } - return _this; -} - -/****************************************************************** - * ??_Gbad_typeid@@UAEPAXI@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_scalar_dtor,8) -void * __stdcall MSVCRT_bad_typeid_scalar_dtor(bad_typeid * _this, unsigned int flags) -{ - TRACE("(%p %x)\n", _this, flags); - MSVCRT_bad_typeid_dtor(_this); - if (flags & 1) MSVCRT_operator_delete(_this); - return _this; -} - -/****************************************************************** - * ??0__non_rtti_object@@QAE@ABV0@@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_copy_ctor,8) -__non_rtti_object * __stdcall MSVCRT___non_rtti_object_copy_ctor(__non_rtti_object * _this, - const __non_rtti_object * rhs) -{ - TRACE("(%p %p)\n", _this, rhs); - MSVCRT_bad_typeid_copy_ctor(_this, rhs); - _this->vtable = &MSVCRT___non_rtti_object_vtable; - return _this; -} - -/****************************************************************** - * ??0__non_rtti_object@@QAE@PBD@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_ctor,8) -__non_rtti_object * __stdcall MSVCRT___non_rtti_object_ctor(__non_rtti_object * _this, - const char * name) -{ - TRACE("(%p %s)\n", _this, name); - EXCEPTION_ctor(_this, &name); - _this->vtable = &MSVCRT___non_rtti_object_vtable; - return _this; -} - -/****************************************************************** - * ??1__non_rtti_object@@UAE@XZ (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_dtor,4) -void __stdcall MSVCRT___non_rtti_object_dtor(__non_rtti_object * _this) -{ - TRACE("(%p)\n", _this); - MSVCRT_bad_typeid_dtor(_this); -} - -/****************************************************************** - * ??4__non_rtti_object@@QAEAAV0@ABV0@@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_opequals,8) -__non_rtti_object * __stdcall MSVCRT___non_rtti_object_opequals(__non_rtti_object * _this, - const __non_rtti_object *rhs) -{ - TRACE("(%p %p)\n", _this, rhs); - MSVCRT_bad_typeid_opequals(_this, rhs); - return _this; -} - -/****************************************************************** - * ??_E__non_rtti_object@@UAEPAXI@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_vector_dtor,8) -void * __stdcall MSVCRT___non_rtti_object_vector_dtor(__non_rtti_object * _this, unsigned int flags) -{ - TRACE("(%p %x)\n", _this, flags); - if (flags & 2) - { - /* we have an array, with the number of elements stored before the first object */ - int i, *ptr = (int *)_this - 1; - - for (i = *ptr - 1; i >= 0; i--) MSVCRT___non_rtti_object_dtor(_this + i); - MSVCRT_operator_delete(ptr); - } - else - { - MSVCRT___non_rtti_object_dtor(_this); - if (flags & 1) MSVCRT_operator_delete(_this); - } - return _this; -} - -/****************************************************************** - * ??_G__non_rtti_object@@UAEPAXI@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_scalar_dtor,8) -void * __stdcall MSVCRT___non_rtti_object_scalar_dtor(__non_rtti_object * _this, unsigned int flags) -{ - TRACE("(%p %x)\n", _this, flags); - MSVCRT___non_rtti_object_dtor(_this); - if (flags & 1) MSVCRT_operator_delete(_this); - return _this; -} - -/****************************************************************** - * ??0bad_cast@@AAE@PBQBD@Z (MSVCRT.@) - * ??0bad_cast@@QAE@ABQBD@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_ctor,8) -bad_cast * __stdcall MSVCRT_bad_cast_ctor(bad_cast * _this, const char ** name) -{ - TRACE("(%p %s)\n", _this, *name); - EXCEPTION_ctor(_this, name); - _this->vtable = &MSVCRT_bad_cast_vtable; - return _this; -} - -/****************************************************************** - * ??0bad_cast@@QAE@ABV0@@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_copy_ctor,8) -bad_cast * __stdcall MSVCRT_bad_cast_copy_ctor(bad_cast * _this, const bad_cast * rhs) -{ - TRACE("(%p %p)\n", _this, rhs); - MSVCRT_exception_copy_ctor(_this, rhs); - _this->vtable = &MSVCRT_bad_cast_vtable; - return _this; -} - -/****************************************************************** - * ??0bad_cast@@QAE@PBD@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_ctor_charptr,8) -bad_cast * __stdcall MSVCRT_bad_cast_ctor_charptr(bad_cast * _this, const char * name) -{ - TRACE("(%p %s)\n", _this, name); - EXCEPTION_ctor(_this, &name); - _this->vtable = &MSVCRT_bad_cast_vtable; - return _this; -} - -/****************************************************************** - * ??_Fbad_cast@@QAEXXZ (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_default_ctor,4) -bad_cast * __stdcall MSVCRT_bad_cast_default_ctor(bad_cast * _this) -{ - return MSVCRT_bad_cast_ctor_charptr( _this, "bad cast" ); -} - -/****************************************************************** - * ??1bad_cast@@UAE@XZ (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_dtor,4) -void __stdcall MSVCRT_bad_cast_dtor(bad_cast * _this) -{ - TRACE("(%p)\n", _this); - MSVCRT_exception_dtor(_this); -} - -/****************************************************************** - * ??4bad_cast@@QAEAAV0@ABV0@@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_opequals,8) -bad_cast * __stdcall MSVCRT_bad_cast_opequals(bad_cast * _this, const bad_cast * rhs) -{ - TRACE("(%p %p)\n", _this, rhs); - MSVCRT_exception_opequals(_this, rhs); - return _this; -} - -/****************************************************************** - * ??_Ebad_cast@@UAEPAXI@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_vector_dtor,8) -void * __stdcall MSVCRT_bad_cast_vector_dtor(bad_cast * _this, unsigned int flags) -{ - TRACE("(%p %x)\n", _this, flags); - if (flags & 2) - { - /* we have an array, with the number of elements stored before the first object */ - int i, *ptr = (int *)_this - 1; - - for (i = *ptr - 1; i >= 0; i--) MSVCRT_bad_cast_dtor(_this + i); - MSVCRT_operator_delete(ptr); - } - else - { - MSVCRT_bad_cast_dtor(_this); - if (flags & 1) MSVCRT_operator_delete(_this); - } - return _this; -} - -/****************************************************************** - * ??_Gbad_cast@@UAEPAXI@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_scalar_dtor,8) -void * __stdcall MSVCRT_bad_cast_scalar_dtor(bad_cast * _this, unsigned int flags) -{ - TRACE("(%p %x)\n", _this, flags); - MSVCRT_bad_cast_dtor(_this); - if (flags & 1) MSVCRT_operator_delete(_this); - return _this; -} - -/****************************************************************** - * ??8type_info@@QBEHABV0@@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_opequals_equals,8) -int __stdcall MSVCRT_type_info_opequals_equals(type_info * _this, const type_info * rhs) -{ - int ret = !strcmp(_this->mangled + 1, rhs->mangled + 1); - TRACE("(%p %p) returning %d\n", _this, rhs, ret); - return ret; -} - -/****************************************************************** - * ??9type_info@@QBEHABV0@@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_opnot_equals,8) -int __stdcall MSVCRT_type_info_opnot_equals(type_info * _this, const type_info * rhs) -{ - int ret = !!strcmp(_this->mangled + 1, rhs->mangled + 1); - TRACE("(%p %p) returning %d\n", _this, rhs, ret); - return ret; -} - -/****************************************************************** - * ?before@type_info@@QBEHABV1@@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_before,8) -int __stdcall MSVCRT_type_info_before(type_info * _this, const type_info * rhs) -{ - int ret = strcmp(_this->mangled + 1, rhs->mangled + 1) < 0; - TRACE("(%p %p) returning %d\n", _this, rhs, ret); - return ret; -} - -/****************************************************************** - * ??1type_info@@UAE@XZ (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_dtor,4) -void __stdcall MSVCRT_type_info_dtor(type_info * _this) -{ - TRACE("(%p)\n", _this); - MSVCRT_free(_this->name); -} - -/****************************************************************** - * ?name@type_info@@QBEPBDXZ (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_name,4) -const char * __stdcall MSVCRT_type_info_name(type_info * _this) -{ - if (!_this->name) - { - /* Create and set the demangled name */ - /* Note: mangled name in type_info struct always starts with a '.', while - * it isn't valid for mangled name. - * Is this '.' really part of the mangled name, or has it some other meaning ? - */ - char* name = __unDName(0, _this->mangled + 1, 0, - MSVCRT_malloc, MSVCRT_free, UNDNAME_NO_ARGUMENTS | UNDNAME_32_BIT_DECODE); - if (name) - { - size_t len = strlen(name); - - /* It seems _unDName may leave blanks at the end of the demangled name */ - while (len && name[--len] == ' ') - name[len] = '\0'; - - if (InterlockedCompareExchangePointer((void**)&_this->name, name, NULL)) - { - /* Another thread set this member since we checked above - use it */ - MSVCRT_free(name); - } - } - } - TRACE("(%p) returning %s\n", _this, _this->name); - return _this->name; -} - -/****************************************************************** - * ?raw_name@type_info@@QBEPBDXZ (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_raw_name,4) -const char * __stdcall MSVCRT_type_info_raw_name(type_info * _this) -{ - TRACE("(%p) returning %s\n", _this, _this->mangled); - return _this->mangled; -} - -/* Unexported */ -DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_vector_dtor,8) -void * __stdcall MSVCRT_type_info_vector_dtor(type_info * _this, unsigned int flags) -{ - TRACE("(%p %x)\n", _this, flags); - if (flags & 2) - { - /* we have an array, with the number of elements stored before the first object */ - int i, *ptr = (int *)_this - 1; - - for (i = *ptr - 1; i >= 0; i--) MSVCRT_type_info_dtor(_this + i); - MSVCRT_operator_delete(ptr); - } - else - { - MSVCRT_type_info_dtor(_this); - if (flags & 1) MSVCRT_operator_delete(_this); - } - return _this; -} - -/* vtables */ - -#ifdef __GNUC__ -#ifdef _WIN64 - -#define __ASM_VTABLE(name,funcs) \ - __asm__(".data\n" \ - "\t.align 8\n" \ - "\t.quad " __ASM_NAME(#name "_rtti") "\n" \ - "\t.globl " __ASM_NAME("MSVCRT_" #name "_vtable") "\n" \ - __ASM_NAME("MSVCRT_" #name "_vtable") ":\n" \ - "\t.quad " THISCALL_NAME(MSVCRT_ ## name ## _vector_dtor) "\n" \ - funcs "\n\t.text"); - -#define __ASM_EXCEPTION_VTABLE(name) \ - __ASM_VTABLE(name, "\t.quad " THISCALL_NAME(MSVCRT_what_exception) ) - -#else - -#define __ASM_VTABLE(name,funcs) \ - __asm__(".data\n" \ - "\t.align 4\n" \ - "\t.long " __ASM_NAME(#name "_rtti") "\n" \ - "\t.globl " __ASM_NAME("MSVCRT_" #name "_vtable") "\n" \ - __ASM_NAME("MSVCRT_" #name "_vtable") ":\n" \ - "\t.long " THISCALL_NAME(MSVCRT_ ## name ## _vector_dtor) "\n" \ - funcs "\n\t.text"); - -#define __ASM_EXCEPTION_VTABLE(name) \ - __ASM_VTABLE(name, "\t.long " THISCALL_NAME(MSVCRT_what_exception) ) - -#endif /* _WIN64 */ - -#ifndef __GNUC__ -void __asm_dummy_vtables(void) { -#endif - -__ASM_VTABLE(type_info,"") -__ASM_EXCEPTION_VTABLE(exception) -__ASM_EXCEPTION_VTABLE(bad_typeid) -__ASM_EXCEPTION_VTABLE(bad_cast) -__ASM_EXCEPTION_VTABLE(__non_rtti_object) - -#ifndef __GNUC__ -} -#endif -#endif - -/* Static RTTI for exported objects */ - -static const type_info exception_type_info = -{ - &MSVCRT_type_info_vtable, - NULL, - ".?AVexception@@" -}; - -static const rtti_base_descriptor exception_rtti_base_descriptor = -{ - &exception_type_info, - 0, - { 0, -1, 0 }, - 0 -}; - -static const rtti_base_array exception_rtti_base_array = -{ - { - &exception_rtti_base_descriptor, - NULL, - NULL - } -}; - -static const rtti_object_hierarchy exception_type_hierarchy = -{ - 0, - 0, - 1, - &exception_rtti_base_array -}; - -const rtti_object_locator exception_rtti = -{ - 0, - 0, - 0, - &exception_type_info, - &exception_type_hierarchy -}; - -static const cxx_type_info exception_cxx_type_info = -{ - 0, - &exception_type_info, - { 0, -1, 0 }, - sizeof(exception), - (cxx_copy_ctor)THISCALL(MSVCRT_exception_copy_ctor) -}; - -static const type_info bad_typeid_type_info = -{ - &MSVCRT_type_info_vtable, - NULL, - ".?AVbad_typeid@@" -}; - -static const rtti_base_descriptor bad_typeid_rtti_base_descriptor = -{ - &bad_typeid_type_info, - 1, - { 0, -1, 0 }, - 0 -}; - -static const rtti_base_array bad_typeid_rtti_base_array = -{ - { - &bad_typeid_rtti_base_descriptor, - &exception_rtti_base_descriptor, - NULL - } -}; - -static const rtti_object_hierarchy bad_typeid_type_hierarchy = -{ - 0, - 0, - 2, - &bad_typeid_rtti_base_array -}; - -const rtti_object_locator bad_typeid_rtti = -{ - 0, - 0, - 0, - &bad_typeid_type_info, - &bad_typeid_type_hierarchy -}; - -static const cxx_type_info bad_typeid_cxx_type_info = -{ - 0, - &bad_typeid_type_info, - { 0, -1, 0 }, - sizeof(exception), - (cxx_copy_ctor)THISCALL(MSVCRT_bad_typeid_copy_ctor) -}; - -static const type_info bad_cast_type_info = -{ - &MSVCRT_type_info_vtable, - NULL, - ".?AVbad_cast@@" -}; - -static const rtti_base_descriptor bad_cast_rtti_base_descriptor = -{ - &bad_cast_type_info, - 1, - { 0, -1, 0 }, - 0 -}; - -static const rtti_base_array bad_cast_rtti_base_array = -{ - { - &bad_cast_rtti_base_descriptor, - &exception_rtti_base_descriptor, - NULL - } -}; - -static const rtti_object_hierarchy bad_cast_type_hierarchy = -{ - 0, - 0, - 2, - &bad_cast_rtti_base_array -}; - -const rtti_object_locator bad_cast_rtti = -{ - 0, - 0, - 0, - &bad_cast_type_info, - &bad_cast_type_hierarchy -}; - -static const cxx_type_info bad_cast_cxx_type_info = -{ - 0, - &bad_cast_type_info, - { 0, -1, 0 }, - sizeof(exception), - (cxx_copy_ctor)THISCALL(MSVCRT_bad_cast_copy_ctor) -}; - -static const type_info __non_rtti_object_type_info = -{ - &MSVCRT_type_info_vtable, - NULL, - ".?AV__non_rtti_object@@" -}; - -static const rtti_base_descriptor __non_rtti_object_rtti_base_descriptor = -{ - &__non_rtti_object_type_info, - 2, - { 0, -1, 0 }, - 0 -}; - -static const rtti_base_array __non_rtti_object_rtti_base_array = -{ - { - &__non_rtti_object_rtti_base_descriptor, - &bad_typeid_rtti_base_descriptor, - &exception_rtti_base_descriptor - } -}; - -static const rtti_object_hierarchy __non_rtti_object_type_hierarchy = -{ - 0, - 0, - 3, - &__non_rtti_object_rtti_base_array -}; - -const rtti_object_locator __non_rtti_object_rtti = -{ - 0, - 0, - 0, - &__non_rtti_object_type_info, - &__non_rtti_object_type_hierarchy -}; - -static const cxx_type_info __non_rtti_object_cxx_type_info = -{ - 0, - &__non_rtti_object_type_info, - { 0, -1, 0 }, - sizeof(exception), - (cxx_copy_ctor)THISCALL(MSVCRT___non_rtti_object_copy_ctor) -}; - -static const type_info type_info_type_info = -{ - &MSVCRT_type_info_vtable, - NULL, - ".?AVtype_info@@" -}; - -static const rtti_base_descriptor type_info_rtti_base_descriptor = -{ - &type_info_type_info, - 0, - { 0, -1, 0 }, - 0 -}; - -static const rtti_base_array type_info_rtti_base_array = -{ - { - &type_info_rtti_base_descriptor, - NULL, - NULL - } -}; - -static const rtti_object_hierarchy type_info_type_hierarchy = -{ - 0, - 0, - 1, - &type_info_rtti_base_array -}; - -const rtti_object_locator type_info_rtti = -{ - 0, - 0, - 0, - &type_info_type_info, - &type_info_type_hierarchy -}; - -/* - * Exception RTTI for cpp objects - */ -static const cxx_type_info_table bad_cast_type_info_table = -{ - 3, - { - &__non_rtti_object_cxx_type_info, - &bad_typeid_cxx_type_info, - &exception_cxx_type_info - } -}; - -static const cxx_exception_type bad_cast_exception_type = -{ - 0, - (void*)THISCALL(MSVCRT_bad_cast_dtor), - NULL, - &bad_cast_type_info_table -}; - -static const cxx_type_info_table bad_typeid_type_info_table = -{ - 2, - { - &bad_cast_cxx_type_info, - &exception_cxx_type_info, - NULL - } -}; - -static const cxx_exception_type bad_typeid_exception_type = -{ - 0, - (void*)THISCALL(MSVCRT_bad_typeid_dtor), - NULL, - &bad_cast_type_info_table -}; - -static const cxx_exception_type __non_rtti_object_exception_type = -{ - 0, - (void*)THISCALL(MSVCRT___non_rtti_object_dtor), - NULL, - &bad_typeid_type_info_table -}; - - -/****************************************************************** - * ?set_terminate@@YAP6AXXZP6AXXZ@Z (MSVCRT.@) - * - * Install a handler to be called when terminate() is called. - * - * PARAMS - * func [I] Handler function to install - * - * RETURNS - * The previously installed handler function, if any. - */ -terminate_function CDECL MSVCRT_set_terminate(terminate_function func) -{ - thread_data_t *data = msvcrt_get_thread_data(); - terminate_function previous = data->terminate_handler; - TRACE("(%p) returning %p\n",func,previous); - data->terminate_handler = func; - return previous; -} - -/****************************************************************** - * _get_terminate (MSVCRT.@) - */ -terminate_function CDECL _get_terminate(void) -{ - thread_data_t *data = msvcrt_get_thread_data(); - return data->terminate_handler; -} - -/****************************************************************** - * ?set_unexpected@@YAP6AXXZP6AXXZ@Z (MSVCRT.@) - * - * Install a handler to be called when unexpected() is called. - * - * PARAMS - * func [I] Handler function to install - * - * RETURNS - * The previously installed handler function, if any. - */ -unexpected_function CDECL MSVCRT_set_unexpected(unexpected_function func) -{ - thread_data_t *data = msvcrt_get_thread_data(); - unexpected_function previous = data->unexpected_handler; - TRACE("(%p) returning %p\n",func,previous); - data->unexpected_handler = func; - return previous; -} - -/****************************************************************** - * _get_unexpected (MSVCRT.@) - */ -unexpected_function CDECL _get_unexpected(void) -{ - thread_data_t *data = msvcrt_get_thread_data(); - return data->unexpected_handler; -} - -/****************************************************************** - * ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z (MSVCRT.@) - */ -_se_translator_function CDECL MSVCRT__set_se_translator(_se_translator_function func) -{ - thread_data_t *data = msvcrt_get_thread_data(); - _se_translator_function previous = data->se_translator; - TRACE("(%p) returning %p\n",func,previous); - data->se_translator = func; - return previous; -} - -/****************************************************************** - * ?terminate@@YAXXZ (MSVCRT.@) - * - * Default handler for an unhandled exception. - * - * PARAMS - * None. - * - * RETURNS - * This function does not return. Either control resumes from any - * handler installed by calling set_terminate(), or (by default) abort() - * is called. - */ -void CDECL MSVCRT_terminate(void) -{ - thread_data_t *data = msvcrt_get_thread_data(); - if (data->terminate_handler) data->terminate_handler(); - abort(); -} - -/****************************************************************** - * ?unexpected@@YAXXZ (MSVCRT.@) - */ -void CDECL MSVCRT_unexpected(void) -{ - thread_data_t *data = msvcrt_get_thread_data(); - if (data->unexpected_handler) data->unexpected_handler(); - MSVCRT_terminate(); -} - - -/****************************************************************** - * __RTtypeid (MSVCRT.@) - * - * Retrieve the Run Time Type Information (RTTI) for a C++ object. - * - * PARAMS - * cppobj [I] C++ object to get type information for. - * - * RETURNS - * Success: A type_info object describing cppobj. - * Failure: If the object to be cast has no RTTI, a __non_rtti_object - * exception is thrown. If cppobj is NULL, a bad_typeid exception - * is thrown. In either case, this function does not return. - * - * NOTES - * This function is usually called by compiler generated code as a result - * of using one of the C++ dynamic cast statements. - */ -const type_info* CDECL MSVCRT___RTtypeid(void *cppobj) -{ - const type_info *ret; - - if (!cppobj) - { - bad_typeid e; - MSVCRT_bad_typeid_ctor( &e, "Attempted a typeid of NULL pointer!" ); - _CxxThrowException( &e, &bad_typeid_exception_type ); - return NULL; - } - - __TRY - { - const rtti_object_locator *obj_locator = get_obj_locator( cppobj ); - ret = obj_locator->type_descriptor; - } - __EXCEPT_PAGE_FAULT - { - __non_rtti_object e; - MSVCRT___non_rtti_object_ctor( &e, "Bad read pointer - no RTTI data!" ); - _CxxThrowException( &e, &__non_rtti_object_exception_type ); - return NULL; - } - __ENDTRY - return ret; -} - -/****************************************************************** - * __RTDynamicCast (MSVCRT.@) - * - * Dynamically cast a C++ object to one of its base classes. - * - * PARAMS - * cppobj [I] Any C++ object to cast - * unknown [I] Reserved, set to 0 - * src [I] type_info object describing cppobj - * dst [I] type_info object describing the base class to cast to - * do_throw [I] TRUE = throw an exception if the cast fails, FALSE = don't - * - * RETURNS - * Success: The address of cppobj, cast to the object described by dst. - * Failure: NULL, If the object to be cast has no RTTI, or dst is not a - * valid cast for cppobj. If do_throw is TRUE, a bad_cast exception - * is thrown and this function does not return. - * - * NOTES - * This function is usually called by compiler generated code as a result - * of using one of the C++ dynamic cast statements. - */ -void* CDECL MSVCRT___RTDynamicCast(void *cppobj, int unknown, - type_info *src, type_info *dst, - int do_throw) -{ - void *ret; - - if (!cppobj) return NULL; - - TRACE("obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)\n", - cppobj, unknown, src, dbgstr_type_info(src), dst, dbgstr_type_info(dst), do_throw); - - /* To cast an object at runtime: - * 1.Find out the true type of the object from the typeinfo at vtable[-1] - * 2.Search for the destination type in the class hierarchy - * 3.If destination type is found, return base object address + dest offset - * Otherwise, fail the cast - * - * FIXME: the unknown parameter doesn't seem to be used for anything - */ - __TRY - { - int i; - const rtti_object_locator *obj_locator = get_obj_locator( cppobj ); - const rtti_object_hierarchy *obj_bases = obj_locator->type_hierarchy; - const rtti_base_descriptor * const* base_desc = obj_bases->base_classes->bases; - - if (TRACE_ON(msvcrt)) dump_obj_locator(obj_locator); - - ret = NULL; - for (i = 0; i < obj_bases->array_len; i++) - { - const type_info *typ = base_desc[i]->type_descriptor; - - if (!strcmp(typ->mangled, dst->mangled)) - { - /* compute the correct this pointer for that base class */ - void *this_ptr = (char *)cppobj - obj_locator->base_class_offset; - ret = get_this_pointer( &base_desc[i]->offsets, this_ptr ); - break; - } - } - /* VC++ sets do_throw to 1 when the result of a dynamic_cast is assigned - * to a reference, since references cannot be NULL. - */ - if (!ret && do_throw) - { - const char *msg = "Bad dynamic_cast!"; - bad_cast e; - MSVCRT_bad_cast_ctor( &e, &msg ); - _CxxThrowException( &e, &bad_cast_exception_type ); - } - } - __EXCEPT_PAGE_FAULT - { - __non_rtti_object e; - MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" ); - _CxxThrowException( &e, &__non_rtti_object_exception_type ); - return NULL; - } - __ENDTRY - return ret; -} - - -/****************************************************************** - * __RTCastToVoid (MSVCRT.@) - * - * Dynamically cast a C++ object to a void*. - * - * PARAMS - * cppobj [I] The C++ object to cast - * - * RETURNS - * Success: The base address of the object as a void*. - * Failure: NULL, if cppobj is NULL or has no RTTI. - * - * NOTES - * This function is usually called by compiler generated code as a result - * of using one of the C++ dynamic cast statements. - */ -void* CDECL MSVCRT___RTCastToVoid(void *cppobj) -{ - void *ret; - - if (!cppobj) return NULL; - - __TRY - { - const rtti_object_locator *obj_locator = get_obj_locator( cppobj ); - ret = (char *)cppobj - obj_locator->base_class_offset; - } - __EXCEPT_PAGE_FAULT - { - __non_rtti_object e; - MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" ); - _CxxThrowException( &e, &__non_rtti_object_exception_type ); - return NULL; - } - __ENDTRY - return ret; -} diff --git a/sdk/lib/crt/except/cppexcept.c b/sdk/lib/crt/except/cppexcept.c deleted file mode 100644 index e1352a608be..00000000000 --- a/sdk/lib/crt/except/cppexcept.c +++ /dev/null @@ -1,596 +0,0 @@ -/* - * msvcrt C++ exception handling - * - * Copyright 2002 Alexandre Julliard - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - * NOTES - * A good reference is the article "How a C++ compiler implements - * exception handling" by Vishal Kochhar, available on - * www.thecodeproject.com. - */ - -#define __WINE_DEBUG_CHANNEL__ -#include <precomp.h> -#include <stdarg.h> - -#include <wine/exception.h> -#include <internal/wine/msvcrt.h> -#include <internal/wine/cppexcept.h> - -#ifdef __i386__ /* CxxFrameHandler is not supported on non-i386 */ - -WINE_DEFAULT_DEBUG_CHANNEL(seh); - -DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame, - PCONTEXT context, EXCEPTION_REGISTRATION_RECORD** dispatch, - const cxx_function_descr *descr, - EXCEPTION_REGISTRATION_RECORD* nested_frame, int nested_trylevel ); - -/* call a function with a given ebp */ -#ifdef _MSC_VER -#pragma warning(disable:4731) // don't warn about modification of ebp -#endif -static inline void *call_ebp_func( void *func, void *_ebp ) -{ - void *result; -#ifdef _MSC_VER - __asm - { - mov eax, func - push ebx - push ebp - mov ebp, _ebp - call eax - pop ebp - pop ebx - mov result, eax - } -#else - int dummy; - __asm__ __volatile__ ("pushl %%ebx\n\t" - "pushl %%ebp\n\t" - "movl %4,%%ebp\n\t" - "call *%%eax\n\t" - "popl %%ebp\n\t" - "popl %%ebx" - : "=a" (result), "=S" (dummy), "=D" (dummy) - : "0" (func), "1" (_ebp) : "ecx", "edx", "memory" ); -#endif - return result; -} -#ifdef _MSC_VER -#pragma warning(default:4731) -#endif - -/* call a copy constructor */ -static inline void call_copy_ctor( void *func, void *this, void *src, int has_vbase ) -{ - TRACE( "calling copy ctor %p object %p src %p\n", func, this, src ); -#ifdef _MSC_VER - if (has_vbase) - { - __asm - { - mov ecx, this - push 1 - push src - call func - } - } - else - { - __asm - { - mov ecx, this - push src - call func - } - } -#else - if (has_vbase) - /* in that case copy ctor takes an extra bool indicating whether to copy the base class */ - __asm__ __volatile__("pushl $1; pushl %2; call *%0" - : : "r" (func), "c" (this), "r" (src) : "eax", "edx", "memory" ); - else - __asm__ __volatile__("pushl %2; call *%0" - : : "r" (func), "c" (this), "r" (src) : "eax", "edx", "memory" ); -#endif -} - -/* call the destructor of the exception object */ -static inline void call_dtor( void *func, void *object ) -{ -#ifdef _MSC_VER - __asm - { - mov ecx, object - call func - } -#else - __asm__ __volatile__("call *%0" : : "r" (func), "c" (object) : "eax", "edx", "memory" ); -#endif -} - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4731) -/* continue execution to the specified address after exception is caught */ -__forceinline void DECLSPEC_NORETURN continue_after_catch( cxx_exception_frame* frame, void *addr ) -{ - __asm - { - mov eax, addr - mov edx, frame - mov esp, [edx-4] - lea ebp, [edx+12] - jmp eax - } - for (;;) ; /* unreached */ -} -#pragma warning(pop) -#else -/* continue execution to the specified address after exception is caught */ -static inline void DECLSPEC_NORETURN continue_after_catch( cxx_exception_frame* frame, void *addr ) -{ - __asm__ __volatile__("movl -4(%0),%%esp; leal 12(%0),%%ebp; jmp *%1" - : : "r" (frame), "a" (addr) ); - for (;;) ; /* unreached */ -} -#endif - -static inline void dump_type( const cxx_type_info *type ) -{ - TRACE( "flags %x type %p %s offsets %d,%d,%d size %d copy ctor %p\n", - type->flags, type->type_info, dbgstr_type_info(type->type_info), - type->offsets.this_offset, type->offsets.vbase_descr, type->offsets.vbase_offset, - type->size, type->copy_ctor ); -} - -static void dump_exception_type( const cxx_exception_type *type ) -{ - UINT i; - - TRACE( "flags %x destr %p handler %p type info %p\n", - type->flags, type->destructor, type->custom_handler, type->type_info_table ); - for (i = 0; i < type->type_info_table->count; i++) - { - TRACE( " %d: ", i ); - dump_type( type->type_info_table->info[i] ); - } -} - -static void dump_function_descr( const cxx_function_descr *descr ) -{ -#ifndef WINE_NO_TRACE_MSGS - UINT i; - int j; - - TRACE( "magic %x\n", descr->magic ); - TRACE( "unwind table: %p %d\n", descr->unwind_table, descr->unwind_count ); - for (i = 0; i < descr->unwind_count; i++) - { - TRACE( " %d: prev %d func %p\n", i, - descr->unwind_table[i].prev, descr->unwind_table[i].handler ); - } - TRACE( "try table: %p %d\n", descr->tryblock, descr->tryblock_count ); - for (i = 0; i < descr->tryblock_count; i++) - { - TRACE( " %d: start %d end %d catchlevel %d catch %p %d\n", i, - descr->tryblock[i].start_level, descr->tryblock[i].end_level, - descr->tryblock[i].catch_level, descr->tryblock[i].catchblock, - descr->tryblock[i].catchblock_count ); - for (j = 0; j < descr->tryblock[i].catchblock_count; j++) - { - const catchblock_info *ptr = &descr->tryblock[i].catchblock[j]; - TRACE( " %d: flags %x offset %d handler %p type %p %s\n", - j, ptr->flags, ptr->offset, ptr->handler, - ptr->type_info, dbgstr_type_info( ptr->type_info ) ); - } - } -#endif - if (descr->magic <= CXX_FRAME_MAGIC_VC6) return; - TRACE( "expect list: %p\n", descr->expect_list ); - if (descr->magic <= CXX_FRAME_MAGIC_VC7) return; - TRACE( "flags: %08x\n", descr->flags ); -} - -/* check if the exception type is caught by a given catch block, and return the type that matched */ -static const cxx_type_info *find_caught_type( cxx_exception_type *exc_type, - const catchblock_info *catchblock ) -{ - UINT i; - - for (i = 0; i < exc_type->type_info_table->count; i++) - { - const cxx_type_info *type = exc_type->type_info_table->info[i]; - - if (!catchblock->type_info) return type; /* catch(...) matches any type */ - if (catchblock->type_info != type->type_info) - { - if (strcmp( catchblock->type_info->mangled, type->type_info->mangled )) continue; - } - /* type is the same, now check the flags */ - if ((exc_type->flags & TYPE_FLAG_CONST) && - !(catchblock->flags & TYPE_FLAG_CONST)) continue; - if ((exc_type->flags & TYPE_FLAG_VOLATILE) && - !(catchblock->flags & TYPE_FLAG_VOLATILE)) continue; - return type; /* it matched */ - } - return NULL; -} - - -/* copy the exception object where the catch block wants it */ -static void copy_exception( void *object, cxx_exception_frame *frame, - const catchblock_info *catchblock, const cxx_type_info *type ) -{ - void **dest_ptr; - - if (!catchblock->type_info || !catchblock->type_info->mangled[0]) return; - if (!catchblock->offset) return; - dest_ptr = (void **)((char *)&frame->ebp + catchblock->offset); - - if (catchblock->flags & TYPE_FLAG_REFERENCE) - { - *dest_ptr = get_this_pointer( &type->offsets, object ); - } - else if (type->flags & CLASS_IS_SIMPLE_TYPE) - { - memmove( dest_ptr, object, type->size ); - /* if it is a pointer, adjust it */ - if (type->size == sizeof(void *)) *dest_ptr = get_this_pointer( &type->offsets, *dest_ptr ); - } - else /* copy the object */ - { - if (type->copy_ctor) - call_copy_ctor( type->copy_ctor, dest_ptr, get_this_pointer(&type->offsets,object), - (type->flags & CLASS_HAS_VIRTUAL_BASE_CLASS) ); - else - memmove( dest_ptr, get_this_pointer(&type->offsets,object), type->size ); - } -} - -/* unwind the local function up to a given trylevel */ -static void cxx_local_unwind( cxx_exception_frame* frame, const cxx_function_descr *descr, int last_level) -{ - void (*handler)(void); - int trylevel = frame->trylevel; - - while (trylevel != last_level) - { - if (trylevel < 0 || (unsigned)trylevel >= descr->unwind_count) - { - ERR( "invalid trylevel %d\n", trylevel ); - MSVCRT_terminate(); - } - handler = descr->unwind_table[trylevel].handler; - if (handler) - { - TRACE( "calling unwind handler %p trylevel %d last %d ebp %p\n", - handler, trylevel, last_level, &frame->ebp ); - call_ebp_func( handler, &frame->ebp ); - } - trylevel = descr->unwind_table[trylevel].prev; - } - frame->trylevel = last_level; -} - -/* exception frame for nested exceptions in catch block */ -struct catch_func_nested_frame -{ - EXCEPTION_REGISTRATION_RECORD frame; /* standard exception frame */ - EXCEPTION_RECORD *prev_rec; /* previous record to restore in thread data */ - cxx_exception_frame *cxx_frame; /* frame of parent exception */ - const cxx_function_descr *descr; /* descriptor of parent exception */ - int trylevel; /* current try level */ - EXCEPTION_RECORD *rec; /* rec associated with frame */ -}; - -/* handler for exceptions happening while calling a catch function */ -static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame, - CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher ) -{ - struct catch_func_nested_frame *nested_frame = (struct catch_func_nested_frame *)frame; - - if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)) - { - msvcrt_get_thread_data()->exc_record = nested_frame->prev_rec; - return ExceptionContinueSearch; - } - - TRACE( "got nested exception in catch function\n" ); - - if(rec->ExceptionCode == CXX_EXCEPTION) - { - PEXCEPTION_RECORD prev_rec = nested_frame->rec; - if(rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0) - { - /* exception was rethrown */ - rec->ExceptionInformation[1] = prev_rec->ExceptionInformation[1]; - rec->ExceptionInformation[2] = prev_rec->ExceptionInformation[2]; - TRACE("detect rethrow: re-propagate: obj: %lx, type: %lx\n", - rec->ExceptionInformation[1], rec->ExceptionInformation[2]); - } - else { - /* new exception in exception handler, destroy old */ - void *object = (void*)prev_rec->ExceptionInformation[1]; - cxx_exception_type *info = (cxx_exception_type*) prev_rec->ExceptionInformation[2]; - TRACE("detect threw new exception in catch block - destroy old(obj: %p type: %p)\n", - object, info); - if(info && info->destructor) - call_dtor( info->destructor, object ); - } - } - - return cxx_frame_handler( rec, nested_frame->cxx_frame, context, - NULL, nested_frame->descr, &nested_frame->frame, - nested_frame->trylevel ); -} - -/* find and call the appropriate catch block for an exception */ -/* returns the address to continue execution to after the catch block was called */ -static inline void call_catch_block( PEXCEPTION_RECORD rec, cxx_exception_frame *frame, - const cxx_function_descr *descr, int nested_trylevel, - cxx_exception_type *info ) -{ - UINT i; - int j; - void *addr, *object = (void *)rec->ExceptionInformation[1]; - struct catch_func_nested_frame nested_frame; - int trylevel = frame->trylevel; - thread_data_t *thread_data = msvcrt_get_thread_data(); - DWORD save_esp = ((DWORD*)frame)[-1]; - - for (i = 0; i < descr->tryblock_count; i++) - { - const tryblock_info *tryblock = &descr->tryblock[i]; - - if (trylevel < tryblock->start_level) continue; - if (trylevel > tryblock->end_level) continue; - - /* got a try block */ - for (j = 0; j < tryblock->catchblock_count; j++) - { - const catchblock_info *catchblock = &tryblock->catchblock[j]; - if(info) - { - const cxx_type_info *type = find_caught_type( info, catchblock ); - if (!type) continue; - - TRACE( "matched type %p in tryblock %d catchblock %d\n", type, i, j ); - - /* copy the exception to its destination on the stack */ - copy_exception( object, frame, catchblock, type ); - } - else - { - /* no CXX_EXCEPTION only proceed with a catch(...) block*/ - if(catchblock->type_info) - continue; - TRACE("found catch(...) block\n"); - } - - /* unwind the stack */ - RtlUnwind( frame, 0, rec, 0 ); - cxx_local_unwind( frame, descr, tryblock->start_level ); - frame->trylevel = tryblock->end_level + 1; - - /* call the catch block */ - TRACE( "calling catch block %p addr %p ebp %p\n", - catchblock, catchblock->handler, &frame->ebp ); - - /* setup an exception block for nested exceptions */ - - nested_frame.frame.Handler = (PEXCEPTION_ROUTINE)catch_function_nested_handler; - nested_frame.prev_rec = thread_data->exc_record; - nested_frame.cxx_frame = frame; - nested_frame.descr = descr; - nested_frame.trylevel = nested_trylevel + 1; - nested_frame.rec = rec; - - __wine_push_frame( &nested_frame.frame ); - thread_data->exc_record = rec; - addr = call_ebp_func( catchblock->handler, &frame->ebp ); - thread_data->exc_record = nested_frame.prev_rec; - __wine_pop_frame( &nested_frame.frame ); - - ((DWORD*)frame)[-1] = save_esp; - if (info && info->destructor) call_dtor( info->destructor, object ); - TRACE( "done, continuing at %p\n", addr ); - - continue_after_catch( frame, addr ); - } - } -} - - -/********************************************************************* - * cxx_frame_handler - * - * Implementation of __CxxFrameHandler. - */ -DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame, - PCONTEXT context, EXCEPTION_REGISTRATION_RECORD** dispatch, - const cxx_function_descr *descr, - EXCEPTION_REGISTRATION_RECORD* nested_frame, - int nested_trylevel ) -{ - cxx_exception_type *exc_type; - - if (descr->magic < CXX_FRAME_MAGIC_VC6 || descr->magic > CXX_FRAME_MAGIC_VC8) - { - ERR( "invalid frame magic %x\n", descr->magic ); - return ExceptionContinueSearch; - } - if (descr->magic >= CXX_FRAME_MAGIC_VC8 && - (descr->flags & FUNC_DESCR_SYNCHRONOUS) && - (rec->ExceptionCode != CXX_EXCEPTION)) - return ExceptionContinueSearch; /* handle only c++ exceptions */ - - if (rec->ExceptionFlags & (EH_UNWINDING|EH_EXIT_UNWIND)) - { - if (descr->unwind_count && !nested_trylevel) cxx_local_unwind( frame, descr, -1 ); - return ExceptionContinueSearch; - } - if (!descr->tryblock_count) return ExceptionContinueSearch; - - if(rec->ExceptionCode == CXX_EXCEPTION) - { - exc_type = (cxx_exception_type *)rec->ExceptionInformation[2]; - - if (rec->ExceptionInformation[0] > CXX_FRAME_MAGIC_VC8 && - exc_type->custom_handler) - { - return exc_type->custom_handler( rec, frame, context, dispatch, - descr, nested_trylevel, nested_frame, 0 ); - } - - if (TRACE_ON(seh)) - { - TRACE("handling C++ exception rec %p frame %p trylevel %d descr %p nested_frame %p\n", - rec, frame, frame->trylevel, descr, nested_frame ); - dump_exception_type( exc_type ); - dump_function_descr( descr ); - } - } - else - { - exc_type = NULL; - TRACE("handling C exception code %x rec %p frame %p trylevel %d descr %p nested_frame %p\n", - rec->ExceptionCode, rec, frame, frame->trylevel, descr, nested_frame ); - } - - call_catch_block( rec, frame, descr, frame->trylevel, exc_type ); - return ExceptionContinueSearch; -} - - -/********************************************************************* - * __CxxFrameHandler (MSVCRT.@) - */ -extern DWORD CDECL __CxxFrameHandler( PEXCEPTION_RECORD rec, EXCEPTION_REGISTRATION_RECORD* frame, - PCONTEXT context, EXCEPTION_REGISTRATION_RECORD** dispatch ); -#ifdef _MSC_VER -DWORD _declspec(naked) __CxxFrameHandler( PEXCEPTION_RECORD rec, EXCEPTION_REGISTRATION_RECORD* frame, - PCONTEXT context, EXCEPTION_REGISTRATION_RECORD** dispatch ) -{ - __asm - { - push 0 - push 0 - push eax - push [esp + 28] - push [esp + 28] - push [esp + 28] - push [esp + 28] - call cxx_frame_handler - add esp, 28 - ret - } -} -#else -__ASM_GLOBAL_FUNC( __CxxFrameHandler, - "pushl $0\n\t" /* nested_trylevel */ - __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") - "pushl $0\n\t" /* nested_frame */ - __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") - "pushl %eax\n\t" /* descr */ - __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") - "pushl 28(%esp)\n\t" /* dispatch */ - __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") - "pushl 28(%esp)\n\t" /* context */ - __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") - "pushl 28(%esp)\n\t" /* frame */ - __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") - "pushl 28(%esp)\n\t" /* rec */ - __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") - "call " __ASM_NAME("cxx_frame_handler") "\n\t" - "add $28,%esp\n\t" - __ASM_CFI(".cfi_adjust_cfa_offset -28\n\t") - "ret" ) -#endif - -/********************************************************************* - * __CxxLongjmpUnwind (MSVCRT.@) - * - * Callback meant to be used as UnwindFunc for setjmp/longjmp. - */ -void __stdcall __CxxLongjmpUnwind( const struct __JUMP_BUFFER *buf ) -{ - cxx_exception_frame *frame = (cxx_exception_frame *)buf->Registration; - const cxx_function_descr *descr = (const cxx_function_descr *)buf->UnwindData[0]; - - TRACE( "unwinding frame %p descr %p trylevel %ld\n", frame, descr, buf->TryLevel ); - cxx_local_unwind( frame, descr, buf->TryLevel ); -} - -#endif /* __i386__ */ - - -/********************************************************************* - * __CppXcptFilter (MSVCRT.@) - */ -int CDECL __CppXcptFilter(NTSTATUS ex, PEXCEPTION_POINTERS ptr) -{ - /* only filter c++ exceptions */ - if (ex != CXX_EXCEPTION) return EXCEPTION_CONTINUE_SEARCH; - return _XcptFilter( ex, ptr ); -} - -/********************************************************************* - * _CxxThrowException (MSVCRT.@) - */ -void WINAPI _CxxThrowException( exception *object, const cxx_exception_type *type ) -{ - ULONG_PTR args[3]; - - args[0] = CXX_FRAME_MAGIC_VC6; - args[1] = (ULONG_PTR)object; - args[2] = (ULONG_PTR)type; - RaiseException( CXX_EXCEPTION, EH_NONCONTINUABLE, 3, args ); -} - -/********************************************************************* - * __CxxDetectRethrow (MSVCRT.@) - */ -BOOL CDECL __CxxDetectRethrow(PEXCEPTION_POINTERS ptrs) -{ - PEXCEPTION_RECORD rec; - - if (!ptrs) - return FALSE; - - rec = ptrs->ExceptionRecord; - - if (rec->ExceptionCode == CXX_EXCEPTION && - rec->NumberParameters == 3 && - rec->ExceptionInformation[0] == CXX_FRAME_MAGIC_VC6 && - rec->ExceptionInformation[2]) - { - ptrs->ExceptionRecord = msvcrt_get_thread_data()->exc_record; - return TRUE; - } - return (msvcrt_get_thread_data()->exc_record == rec); -} - -/********************************************************************* - * __CxxQueryExceptionSize (MSVCRT.@) - */ -unsigned int CDECL __CxxQueryExceptionSize(void) -{ - return sizeof(cxx_exception_type); -} diff --git a/sdk/lib/crt/except/except.c b/sdk/lib/crt/except/except.c deleted file mode 100644 index a3ed19bf545..00000000000 --- a/sdk/lib/crt/except/except.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * msvcrt.dll exception handling - * - * Copyright 2000 Jon Griffiths - * Copyright 2005 Juan Lang - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - * FIXME: Incomplete support for nested exceptions/try block cleanup. - */ - -#include <precomp.h> -#include "excpt.h" -#include "cppexcept.h" -#include <wine/exception.h> - -void CDECL _global_unwind2(EXCEPTION_REGISTRATION_RECORD* frame); - -typedef void (__cdecl *MSVCRT_security_error_handler)(int, void *); -static MSVCRT_security_error_handler security_error_handler; - -/* VC++ extensions to Win32 SEH */ -typedef struct _SCOPETABLE -{ - int previousTryLevel; - int (*lpfnFilter)(PEXCEPTION_POINTERS); - int (*lpfnHandler)(void); -} SCOPETABLE, *PSCOPETABLE; - -typedef struct _MSVCRT_EXCEPTION_FRAME -{ - EXCEPTION_REGISTRATION_RECORD *prev; - void (*handler)(PEXCEPTION_RECORD, EXCEPTION_REGISTRATION_RECORD*, - PCONTEXT, PEXCEPTION_RECORD); - PSCOPETABLE scopetable; - int trylevel; - int _ebp; - PEXCEPTION_POINTERS xpointers; -} MSVCRT_EXCEPTION_FRAME; - -typedef struct -{ - int gs_cookie_offset; - ULONG gs_cookie_xor; - int eh_cookie_offset; - ULONG eh_cookie_xor; - SCOPETABLE entries[1]; -} SCOPETABLE_V4; - -#ifdef __i386__ - -static const SCOPETABLE_V4 *get_scopetable_v4( MSVCRT_EXCEPTION_FRAME *frame, ULONG_PTR cookie ) -{ - return (const SCOPETABLE_V4 *)((ULONG_PTR)frame->scopetable ^ cookie); -} - -#if defined(__GNUC__) -static inline void call_finally_block( void *code_block, void *base_ptr ) -{ - __asm__ __volatile__ ("movl %1,%%ebp; call *%%eax" - : : "a" (code_block), "g" (base_ptr)); -} - -static inline int call_filter( int (*func)(PEXCEPTION_POINTERS), void *arg, void *ebp ) -{ - int ret; - __asm__ __volatile__ ("pushl %%ebp; pushl %3; movl %2,%%ebp; call *%%eax; popl %%ebp; popl %%ebp" - : "=a" (ret) - : "0" (func), "r" (ebp), "r" (arg) - : "ecx", "edx", "memory" ); - return ret; -} -static inline int call_unwind_func( int (*func)(void), void *ebp ) -{ - int ret; - __asm__ __volatile__ ("pushl %%ebp\n\t" - "pushl %%ebx\n\t" - "pushl %%esi\n\t" - "pushl %%edi\n\t" - "movl %2,%%ebp\n\t" - "call *%0\n\t" - "popl %%edi\n\t" - "popl %%esi\n\t" - "popl %%ebx\n\t" - "popl %%ebp" - : "=a" (ret) - : "0" (func), "r" (ebp) - : "ecx", "edx", "memory" ); - return ret; -} -#elif defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable:4731) // Don't complain about changing ebp -void __inline call_finally_block( void *code_block, void *base_ptr ) -{ - __asm - { - mov eax, code_block - mov ebp, base_ptr - call [eax] - } -} - -int __inline call_filter( int (*func)(PEXCEPTION_POINTERS), void *arg, void *_ebp ) -{ - int _ret; - __asm - { - push ebp - mov eax, arg - push eax - mov ebp, _ebp - mov eax, func - call [eax] - mov _ret, eax - pop ebp - pop ebp - } - return _ret; -} -int __inline call_unwind_func( int (*func)(void), void *_ebp ) -{ - int _ret; - - __asm - { - push ebp - push ebx - push esi - push edi - mov ebp, _ebp - call dword ptr [func] - mov _ret, eax - pop edi - pop esi - pop ebx - pop ebp - } - return _ret; -} -#pragma warning(pop) -#endif - -static DWORD MSVCRT_nested_handler(PEXCEPTION_RECORD rec, - EXCEPTION_REGISTRATION_RECORD* frame, - PCONTEXT context, - EXCEPTION_REGISTRATION_RECORD** dispatch) -{ - if (!(rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))) - return ExceptionContinueSearch; - *dispatch = frame; - return ExceptionCollidedUnwind; -} - -void msvcrt_local_unwind4( ULONG *cookie, MSVCRT_EXCEPTION_FRAME* frame, int trylevel, void *ebp ) -{ - EXCEPTION_REGISTRATION_RECORD reg; - const SCOPETABLE_V4 *scopetable = get_scopetable_v4( frame, *cookie ); - - TRACE("(%p,%d,%d)\n",frame, frame->trylevel, trylevel); - - /* Register a handler in case of a nested exception */ - reg.Handler = (PEXCEPTION_ROUTINE)MSVCRT_nested_handler; - reg.Prev = NtCurrentTeb()->NtTib.ExceptionList; - __wine_push_frame(®); - - while (frame->trylevel != -2 && frame->trylevel != trylevel) - { - int level = frame->trylevel; - frame->trylevel = scopetable->entries[level].previousTryLevel; - if (!scopetable->entries[level].lpfnFilter) - { - TRACE( "__try block cleanup level %d handler %p ebp %p\n", - level, scopetable->entries[level].lpfnHandler, ebp ); - call_unwind_func( scopetable->entries[level].lpfnHandler, ebp ); - } - } - __wine_pop_frame(®); - TRACE("unwound OK\n"); -} - -/********************************************************************* - * _except_handler4_common (MSVCRT.@) - */ -int CDECL _except_handler4_common( ULONG *cookie, void (*check_cookie)(void), - EXCEPTION_RECORD *rec, MSVCRT_EXCEPTION_FRAME *frame, - CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher ) -{ - int retval, trylevel; - EXCEPTION_POINTERS exceptPtrs; - const SCOPETABLE_V4 *scope_table = get_scopetable_v4( frame, *cookie ); - - TRACE( "exception %x flags=%x at %p handler=%p %p %p cookie=%x scope table=%p cookies=%d/%x,%d/%x\n", - rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress, - frame->handler, context, dispatcher, *cookie, scope_table, - scope_table->gs_cookie_offset, scope_table->gs_cookie_xor, - scope_table->eh_cookie_offset, scope_table->eh_cookie_xor ); - - /* FIXME: no cookie validation yet */ - - if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)) - { - /* Unwinding the current frame */ - msvcrt_local_unwind4( cookie, frame, -2, &frame->_ebp ); - TRACE("unwound current frame, returning ExceptionContinueSearch\n"); - return ExceptionContinueSearch; - } - else - { - /* Hunting for handler */ - exceptPtrs.ExceptionRecord = rec; - exceptPtrs.ContextRecord = context; - *((DWORD *)frame-1) = (DWORD)&exceptPtrs; - trylevel = frame->trylevel; - - while (trylevel != -2) - { - TRACE( "level %d prev %d filter %p\n", trylevel, - scope_table->entries[trylevel].previousTryLevel, - scope_table->entries[trylevel].lpfnFilter ); - if (scope_table->entries[trylevel].lpfnFilter) - { - retval = call_filter( scope_table->entries[trylevel].lpfnFilter, &exceptPtrs, &frame->_ebp ); - - TRACE("filter returned %s\n", retval == EXCEPTION_CONTINUE_EXECUTION ? - "CONTINUE_EXECUTION" : retval == EXCEPTION_EXECUTE_HANDLER ? - "EXECUTE_HANDLER" : "CONTINUE_SEARCH"); - - if (retval == EXCEPTION_CONTINUE_EXECUTION) - return ExceptionContinueExecution; - - if (retval == EXCEPTION_EXECUTE_HANDLER) - { - /* Unwind all higher frames, this one will handle the exception */ - _global_unwind2((EXCEPTION_REGISTRATION_RECORD*)frame); - msvcrt_local_unwind4( cookie, frame, trylevel, &frame->_ebp ); - - /* Set our trylevel to the enclosing block, and call the __finally - * code, which won't return - */ - frame->trylevel = scope_table->entries[trylevel].previousTryLevel; - TRACE("__finally block %p\n",scope_table->entries[trylevel].lpfnHandler); - call_finally_block(scope_table->entries[trylevel].lpfnHandler, &frame->_ebp); - ERR("Returned from __finally block - expect crash!\n"); - } - } - trylevel = scope_table->entries[trylevel].previousTryLevel; - } - } - TRACE("reached -2, returning ExceptionContinueSearch\n"); - return ExceptionContinueSearch; -} - -/******************************************************************* - * _local_unwind4 (MSVCRT.@) - */ -void CDECL _local_unwind4( ULONG *cookie, MSVCRT_EXCEPTION_FRAME* frame, int trylevel ) -{ - msvcrt_local_unwind4( cookie, frame, trylevel, &frame->_ebp ); -} - -/********************************************************************* - * _seh_longjmp_unwind4 (MSVCRT.@) - */ -void __stdcall _seh_longjmp_unwind4(struct __JUMP_BUFFER *jmp) -{ - msvcrt_local_unwind4( (void *)jmp->Cookie, (MSVCRT_EXCEPTION_FRAME *)jmp->Registration, - jmp->TryLevel, (void *)jmp->Ebp ); -} - -#endif - -/****************************************************************** - * __uncaught_exception - */ -BOOL CDECL __uncaught_exception(void) -{ - return FALSE; -} - -/* _set_security_error_handler - not exported in native msvcrt, added in msvcr70 */ -MSVCRT_security_error_handler CDECL _set_security_error_handler( - MSVCRT_security_error_handler handler ) -{ - MSVCRT_security_error_handler old = security_error_handler; - - TRACE("(%p)\n", handler); - - security_error_handler = handler; - return old; -} - -/********************************************************************* - * __DestructExceptionObject (MSVCRT.@) - */ -void CDECL __DestructExceptionObject(EXCEPTION_RECORD* rec) -{ - cxx_exception_type* info = (cxx_exception_type*)rec->ExceptionInformation[2]; - void* object = (void*)rec->ExceptionInformation[1]; - - TRACE("(%p)\n", rec); - - if (rec->ExceptionCode != CXX_EXCEPTION) return; -#ifndef __x86_64__ - if (rec->NumberParameters != 3) return; -#else - if (rec->NumberParameters != 4) return; -#endif - if (rec->ExceptionInformation[0] < CXX_FRAME_MAGIC_VC6 || - rec->ExceptionInformation[0] > CXX_FRAME_MAGIC_VC8) return; - - if (!info || !info->destructor) - return; - -#if defined(__i386__) - #ifdef _MSC_VER - ((void(__fastcall*)(void*))info->destructor)(object); - #else - __asm__ __volatile__("call *%0" : : "r" (info->destructor), "c" (object) : "eax", "edx", "memory"); - #endif -#elif defined(__x86_64__) - ((void(__cdecl*)(void*))(info->destructor + rec->ExceptionInformation[3]))(object); -#else - ((void(__cdecl*)(void*))info->destructor)(object); -#endif -} diff --git a/sdk/lib/crt/except/i386/cpp.s b/sdk/lib/crt/except/i386/cpp.s index a77d02aa93d..0eaa5bc64f7 100644 --- a/sdk/lib/crt/except/i386/cpp.s +++ b/sdk/lib/crt/except/i386/cpp.s @@ -5,53 +5,53 @@ .code .align 4
-MACRO(DEFINE_THISCALL_WRAPPER, cxxname, stdcallname) -EXTERN &stdcallname:PROC -PUBLIC &cxxname -&cxxname: - pop eax - push ecx - push eax - jmp &stdcallname +MACRO(DEFINE_THISCALL_ALIAS, cxxname, target) +#ifdef _USE_ML + EXTERN ___thiscall&target:PROC + ALIAS <&cxxname> = <___thiscall&target> +#else + PUBLIC cxxname + .weakref &cxxname, &target +#endif ENDM
-DEFINE_THISCALL_WRAPPER ??0exception@@QAE@ABQBD@Z, _MSVCRT_exception_ctor@8 -DEFINE_THISCALL_WRAPPER ??0exception@@QAE@ABQBDH@Z, _MSVCRT_exception_ctor_noalloc@12 -DEFINE_THISCALL_WRAPPER ??0exception@@QAE@ABV0@@Z, _MSVCRT_exception_copy_ctor@8 -DEFINE_THISCALL_WRAPPER ??0exception@@QAE@XZ, _MSVCRT_exception_default_ctor@4 -DEFINE_THISCALL_WRAPPER ??1exception@@UAE@XZ, _MSVCRT_exception_dtor@4 -DEFINE_THISCALL_WRAPPER ??4exception@@QAEAAV0@ABV0@@Z, _MSVCRT_exception_opequals@8 -DEFINE_THISCALL_WRAPPER ??_Eexception@@UAEPAXI@Z, _MSVCRT_exception_vector_dtor@8 -DEFINE_THISCALL_WRAPPER ??_Gexception@@UAEPAXI@Z, _MSVCRT_exception_scalar_dtor@8 -DEFINE_THISCALL_WRAPPER ?what@exception@@UBEPBDXZ, _MSVCRT_what_exception@4 -DEFINE_THISCALL_WRAPPER ??0bad_typeid@@QAE@ABV0@@Z, _MSVCRT_bad_typeid_copy_ctor@8 -DEFINE_THISCALL_WRAPPER ??0bad_typeid@@QAE@PBD@Z, _MSVCRT_bad_typeid_ctor@8 -DEFINE_THISCALL_WRAPPER ??_Fbad_typeid@@QAEXXZ, _MSVCRT_bad_typeid_default_ctor@4 -DEFINE_THISCALL_WRAPPER ??1bad_typeid@@UAE@XZ, _MSVCRT_bad_typeid_dtor@4 -DEFINE_THISCALL_WRAPPER ??4bad_typeid@@QAEAAV0@ABV0@@Z, _MSVCRT_bad_typeid_opequals@8 -DEFINE_THISCALL_WRAPPER ??_Ebad_typeid@@UAEPAXI@Z, _MSVCRT_bad_typeid_vector_dtor@8 -DEFINE_THISCALL_WRAPPER ??_Gbad_typeid@@UAEPAXI@Z, _MSVCRT_bad_typeid_scalar_dtor@8 -DEFINE_THISCALL_WRAPPER ??0__non_rtti_object@@QAE@ABV0@@Z, _MSVCRT___non_rtti_object_copy_ctor@8 -DEFINE_THISCALL_WRAPPER ??0__non_rtti_object@@QAE@PBD@Z, _MSVCRT___non_rtti_object_ctor@8 -DEFINE_THISCALL_WRAPPER ??1__non_rtti_object@@UAE@XZ, _MSVCRT___non_rtti_object_dtor@4 -DEFINE_THISCALL_WRAPPER ??4__non_rtti_object@@QAEAAV0@ABV0@@Z, _MSVCRT___non_rtti_object_opequals@8 -DEFINE_THISCALL_WRAPPER ??_E__non_rtti_object@@UAEPAXI@Z, _MSVCRT___non_rtti_object_vector_dtor@8 -DEFINE_THISCALL_WRAPPER ??_G__non_rtti_object@@UAEPAXI@Z, _MSVCRT___non_rtti_object_scalar_dtor@8 -DEFINE_THISCALL_WRAPPER ??0bad_cast@@AAE@PBQBD@Z, _MSVCRT_bad_cast_ctor@8 -DEFINE_THISCALL_WRAPPER ??0bad_cast@@QAE@ABQBD@Z, _MSVCRT_bad_cast_ctor@8 -DEFINE_THISCALL_WRAPPER ??0bad_cast@@QAE@ABV0@@Z, _MSVCRT_bad_cast_copy_ctor@8 -DEFINE_THISCALL_WRAPPER ??0bad_cast@@QAE@PBD@Z, _MSVCRT_bad_cast_ctor_charptr@8 -DEFINE_THISCALL_WRAPPER ??_Fbad_cast@@QAEXXZ, _MSVCRT_bad_cast_default_ctor@4 -DEFINE_THISCALL_WRAPPER ??1bad_cast@@UAE@XZ, _MSVCRT_bad_cast_dtor@4 -DEFINE_THISCALL_WRAPPER ??4bad_cast@@QAEAAV0@ABV0@@Z, _MSVCRT_bad_cast_opequals@8 -DEFINE_THISCALL_WRAPPER ??_Ebad_cast@@UAEPAXI@Z, _MSVCRT_bad_cast_vector_dtor@8 -DEFINE_THISCALL_WRAPPER ??_Gbad_cast@@UAEPAXI@Z, _MSVCRT_bad_cast_scalar_dtor@8 -DEFINE_THISCALL_WRAPPER ??8type_info@@QBEHABV0@@Z, _MSVCRT_type_info_opequals_equals@8 -DEFINE_THISCALL_WRAPPER ??9type_info@@QBEHABV0@@Z, _MSVCRT_type_info_opnot_equals@8 -DEFINE_THISCALL_WRAPPER ?before@type_info@@QBEHABV1@@Z, _MSVCRT_type_info_before@8 -DEFINE_THISCALL_WRAPPER ??1type_info@@UAE@XZ, _MSVCRT_type_info_dtor@4 -DEFINE_THISCALL_WRAPPER ?name@type_info@@QBEPBDXZ, _MSVCRT_type_info_name@4 -DEFINE_THISCALL_WRAPPER ?raw_name@type_info@@QBEPBDXZ, _MSVCRT_type_info_raw_name@4 +DEFINE_THISCALL_ALIAS ??0exception@@QAE@ABQBD@Z, _MSVCRT_exception_ctor +DEFINE_THISCALL_ALIAS ??0exception@@QAE@ABQBDH@Z, _MSVCRT_exception_ctor_noalloc +DEFINE_THISCALL_ALIAS ??0exception@@QAE@ABV0@@Z, _MSVCRT_exception_copy_ctor +DEFINE_THISCALL_ALIAS ??0exception@@QAE@XZ, _MSVCRT_exception_default_ctor +DEFINE_THISCALL_ALIAS ??1exception@@UAE@XZ, _MSVCRT_exception_dtor +DEFINE_THISCALL_ALIAS ??4exception@@QAEAAV0@ABV0@@Z, _MSVCRT_exception_opequals +DEFINE_THISCALL_ALIAS ??_Eexception@@UAEPAXI@Z, _MSVCRT_exception_vector_dtor +DEFINE_THISCALL_ALIAS ??_Gexception@@UAEPAXI@Z, _MSVCRT_exception_scalar_dtor +DEFINE_THISCALL_ALIAS ?what@exception@@UBEPBDXZ, _MSVCRT_what_exception +DEFINE_THISCALL_ALIAS ??0bad_typeid@@QAE@ABV0@@Z, _MSVCRT_bad_typeid_copy_ctor +DEFINE_THISCALL_ALIAS ??0bad_typeid@@QAE@PBD@Z, _MSVCRT_bad_typeid_ctor +DEFINE_THISCALL_ALIAS ??_Fbad_typeid@@QAEXXZ, _MSVCRT_bad_typeid_default_ctor +DEFINE_THISCALL_ALIAS ??1bad_typeid@@UAE@XZ, _MSVCRT_bad_typeid_dtor +DEFINE_THISCALL_ALIAS ??4bad_typeid@@QAEAAV0@ABV0@@Z, _MSVCRT_bad_typeid_opequals +DEFINE_THISCALL_ALIAS ??_Ebad_typeid@@UAEPAXI@Z, _MSVCRT_bad_typeid_vector_dtor +DEFINE_THISCALL_ALIAS ??_Gbad_typeid@@UAEPAXI@Z, _MSVCRT_bad_typeid_scalar_dtor +DEFINE_THISCALL_ALIAS ??0__non_rtti_object@@QAE@ABV0@@Z, _MSVCRT___non_rtti_object_copy_ctor +DEFINE_THISCALL_ALIAS ??0__non_rtti_object@@QAE@PBD@Z, _MSVCRT___non_rtti_object_ctor +DEFINE_THISCALL_ALIAS ??1__non_rtti_object@@UAE@XZ, _MSVCRT___non_rtti_object_dtor +DEFINE_THISCALL_ALIAS ??4__non_rtti_object@@QAEAAV0@ABV0@@Z, _MSVCRT___non_rtti_object_opequals +DEFINE_THISCALL_ALIAS ??_E__non_rtti_object@@UAEPAXI@Z, _MSVCRT___non_rtti_object_vector_dtor +DEFINE_THISCALL_ALIAS ??_G__non_rtti_object@@UAEPAXI@Z, _MSVCRT___non_rtti_object_scalar_dtor +DEFINE_THISCALL_ALIAS ??0bad_cast@@AAE@PBQBD@Z, _MSVCRT_bad_cast_ctor +DEFINE_THISCALL_ALIAS ??0bad_cast@@QAE@ABQBD@Z, _MSVCRT_bad_cast_ctor +DEFINE_THISCALL_ALIAS ??0bad_cast@@QAE@ABV0@@Z, _MSVCRT_bad_cast_copy_ctor +DEFINE_THISCALL_ALIAS ??0bad_cast@@QAE@PBD@Z, _MSVCRT_bad_cast_ctor_charptr +DEFINE_THISCALL_ALIAS ??_Fbad_cast@@QAEXXZ, _MSVCRT_bad_cast_default_ctor +DEFINE_THISCALL_ALIAS ??1bad_cast@@UAE@XZ, _MSVCRT_bad_cast_dtor +DEFINE_THISCALL_ALIAS ??4bad_cast@@QAEAAV0@ABV0@@Z, _MSVCRT_bad_cast_opequals +DEFINE_THISCALL_ALIAS ??_Ebad_cast@@UAEPAXI@Z, _MSVCRT_bad_cast_vector_dtor +DEFINE_THISCALL_ALIAS ??_Gbad_cast@@UAEPAXI@Z, _MSVCRT_bad_cast_scalar_dtor +DEFINE_THISCALL_ALIAS ??8type_info@@QBEHABV0@@Z, _MSVCRT_type_info_opequals_equals +DEFINE_THISCALL_ALIAS ??9type_info@@QBEHABV0@@Z, _MSVCRT_type_info_opnot_equals +DEFINE_THISCALL_ALIAS ?before@type_info@@QBEHABV1@@Z, _MSVCRT_type_info_before +DEFINE_THISCALL_ALIAS ??1type_info@@UAE@XZ, _MSVCRT_type_info_dtor +DEFINE_THISCALL_ALIAS ?name@type_info@@QBEPBDXZ, _MSVCRT_type_info_name +DEFINE_THISCALL_ALIAS ?raw_name@type_info@@QBEPBDXZ, _MSVCRT_type_info_raw_name
#undef _MSVCRT_ @@ -108,5 +108,63 @@ DEFINE_ALIAS ?terminate@@YAXXZ, _MSVCRT_terminate, PROC DEFINE_ALIAS ?unexpected@@YAXXZ, _MSVCRT_unexpected, PROC
+// void call_copy_ctor( void *func, void *this, void *src, int has_vbase ); +PUBLIC _call_copy_ctor +_call_copy_ctor: + push ebp + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ebp, 0 + mov ebp, esp + CFI_DEF_CFA_REGISTER ebp + push 1 + mov ecx, [ebp + 12] + push dword ptr [ebp + 16] + call dword ptr [ebp + 8] + leave + CFI_DEF_CFA esp, 4 + CFI_SAME_VALUE ebp + ret + +// void DECLSPEC_NORETURN continue_after_catch( cxx_exception_frame* frame, void *addr ); +PUBLIC _continue_after_catch +_continue_after_catch: + mov edx, [esp + 4] + mov eax, [esp + 8] + mov esp, [edx - 4] + lea ebp, [edx + 12] + jmp eax + +// void DECLSPEC_NORETURN call_finally_block( void *code_block, void *base_ptr ); +PUBLIC _call_finally_block +_call_finally_block: + mov ebp, [esp +8] + jmp dword ptr [esp + 4] + +// int call_filter( int (*func)(PEXCEPTION_POINTERS), void *arg, void *ebp ); +PUBLIC _call_filter +_call_filter: + push ebp + push [esp + 12] + mov ebp, [esp + 20] + call dword ptr [esp + 12] + pop ebp + pop ebp + ret + +// void *call_handler( void * (*func)(void), void *ebp ); +PUBLIC _call_handler +_call_handler: + push ebp + push ebx + push esi + push edi + mov ebp, [esp + 24] + call dword ptr [esp + 29] + pop edi + pop esi + pop ebx + pop ebp + ret + END
diff --git a/sdk/lib/crt/except/i386/unwind.c b/sdk/lib/crt/except/i386/unwind.c deleted file mode 100644 index f2317bd826b..00000000000 --- a/sdk/lib/crt/except/i386/unwind.c +++ /dev/null @@ -1,39 +0,0 @@ -#define WIN32_NO_STATUS -#include <precomp.h> -#define NTOS_MODE_USER -#include <setjmp.h> -#include <ndk/umtypes.h> -#include <ndk/extypes.h> -#include <ndk/rtlfuncs.h> - -/* VC++ extensions to Win32 SEH */ -typedef struct _SCOPETABLE -{ - int previousTryLevel; - int (*lpfnFilter)(PEXCEPTION_POINTERS); - int (*lpfnHandler)(void); -} SCOPETABLE, *PSCOPETABLE; - -typedef struct _MSVCRT_EXCEPTION_FRAME -{ - PEXCEPTION_REGISTRATION_RECORD *prev; - void (*handler)(PEXCEPTION_RECORD, PEXCEPTION_REGISTRATION_RECORD, - PCONTEXT, PEXCEPTION_RECORD); - PSCOPETABLE scopetable; - int trylevel; - int _ebp; - PEXCEPTION_POINTERS xpointers; -} MSVCRT_EXCEPTION_FRAME; - -void -_local_unwind2(MSVCRT_EXCEPTION_FRAME *RegistrationFrame, - LONG TryLevel); - -/* - * @implemented -*/ - -void __stdcall _seh_longjmp_unwind(_JUMP_BUFFER *jmp) -{ - _local_unwind2((MSVCRT_EXCEPTION_FRAME*) jmp->Registration, jmp->TryLevel); -} diff --git a/sdk/lib/crt/except/matherr.c b/sdk/lib/crt/except/matherr.c index da94b71ffc4..d7e6c5bf35b 100644 --- a/sdk/lib/crt/except/matherr.c +++ b/sdk/lib/crt/except/matherr.c @@ -47,19 +47,3 @@ void CDECL __setusermatherr(MSVCRT_matherr_func func) MSVCRT_default_matherr_func = func; TRACE(":new matherr handler %p\n", func); } - - -#define _FPIEEE_RECORD void - -/* - * @unimplemented - */ -int _fpieee_flt( - unsigned long exception_code, - struct _EXCEPTION_POINTERS* ExceptionPointer, - int (*handler)(_FPIEEE_RECORD*) - ) -{ - FIXME("Unimplemented!\n"); - return 0; -} diff --git a/sdk/lib/crt/except/xcptfil.c b/sdk/lib/crt/except/xcptfil.c deleted file mode 100644 index c5b8d1d1e76..00000000000 --- a/sdk/lib/crt/except/xcptfil.c +++ /dev/null @@ -1,98 +0,0 @@ -#include <precomp.h> -#include "internal/wine/msvcrt.h" -#include "internal/wine/cppexcept.h" - -typedef void (*sighandler_t)(int); -static sighandler_t sighandlers[NSIG] = { SIG_DFL }; - -/* The exception codes are actually NTSTATUS values */ -static const struct -{ - NTSTATUS status; - int signal; -} float_exception_map[] = { - { EXCEPTION_FLT_DENORMAL_OPERAND, _FPE_DENORMAL }, - { EXCEPTION_FLT_DIVIDE_BY_ZERO, _FPE_ZERODIVIDE }, - { EXCEPTION_FLT_INEXACT_RESULT, _FPE_INEXACT }, - { EXCEPTION_FLT_INVALID_OPERATION, _FPE_INVALID }, - { EXCEPTION_FLT_OVERFLOW, _FPE_OVERFLOW }, - { EXCEPTION_FLT_STACK_CHECK, _FPE_STACKOVERFLOW }, - { EXCEPTION_FLT_UNDERFLOW, _FPE_UNDERFLOW }, -}; - -/* - * @implemented - */ -int CDECL -_XcptFilter(NTSTATUS ExceptionCode, - struct _EXCEPTION_POINTERS * except) -{ - LONG ret = EXCEPTION_CONTINUE_SEARCH; - sighandler_t handler; - - if (!except || !except->ExceptionRecord) - return EXCEPTION_CONTINUE_SEARCH; - - switch (except->ExceptionRecord->ExceptionCode) - { - case EXCEPTION_ACCESS_VIOLATION: - if ((handler = sighandlers[SIGSEGV]) != SIG_DFL) - { - if (handler != SIG_IGN) - { - sighandlers[SIGSEGV] = SIG_DFL; - handler(SIGSEGV); - } - ret = EXCEPTION_CONTINUE_EXECUTION; - } - break; - /* According to msdn, - * the FPE signal handler takes as a second argument the type of - * floating point exception. - */ - case EXCEPTION_FLT_DENORMAL_OPERAND: - case EXCEPTION_FLT_DIVIDE_BY_ZERO: - case EXCEPTION_FLT_INEXACT_RESULT: - case EXCEPTION_FLT_INVALID_OPERATION: - case EXCEPTION_FLT_OVERFLOW: - case EXCEPTION_FLT_STACK_CHECK: - case EXCEPTION_FLT_UNDERFLOW: - if ((handler = sighandlers[SIGFPE]) != SIG_DFL) - { - if (handler != SIG_IGN) - { - unsigned int i; - int float_signal = _FPE_INVALID; - - sighandlers[SIGFPE] = SIG_DFL; - for (i = 0; i < sizeof(float_exception_map) / - sizeof(float_exception_map[0]); i++) - { - if (float_exception_map[i].status == - except->ExceptionRecord->ExceptionCode) - { - float_signal = float_exception_map[i].signal; - break; - } - } - ((float_handler)handler)(SIGFPE, float_signal); - } - ret = EXCEPTION_CONTINUE_EXECUTION; - } - break; - case EXCEPTION_ILLEGAL_INSTRUCTION: - case EXCEPTION_PRIV_INSTRUCTION: - if ((handler = sighandlers[SIGILL]) != SIG_DFL) - { - if (handler != SIG_IGN) - { - sighandlers[SIGILL] = SIG_DFL; - handler(SIGILL); - } - ret = EXCEPTION_CONTINUE_EXECUTION; - } - break; - } - return ret; -} - diff --git a/sdk/lib/crt/include/internal/wine_msc.h b/sdk/lib/crt/include/internal/wine_msc.h index d7c799a09f2..ebe023b48d0 100644 --- a/sdk/lib/crt/include/internal/wine_msc.h +++ b/sdk/lib/crt/include/internal/wine_msc.h @@ -1,50 +1,100 @@
-#define DEFINE_THISCALL_WRAPPER(func, args) \ - void __declspec(naked) __thiscall_ ## func (void) \ - { \ - __asm { pop eax } \ - __asm { push ecx } \ - __asm { push eax } \ - __asm { jmp func } \ - } - -exception * __stdcall MSVCRT_exception_ctor(exception * _this, const char ** name); -exception * __stdcall MSVCRT_exception_ctor_noalloc(exception * _this, char ** name, int noalloc); -exception * __stdcall MSVCRT_exception_copy_ctor(exception * _this, const exception * rhs); -exception * __stdcall MSVCRT_exception_default_ctor(exception * _this); -void __stdcall MSVCRT_exception_dtor(exception * _this); -exception * __stdcall MSVCRT_exception_opequals(exception * _this, const exception * rhs); -void * __stdcall MSVCRT_exception_vector_dtor(exception * _this, unsigned int flags); -void * __stdcall MSVCRT_exception_scalar_dtor(exception * _this, unsigned int flags); -const char * __stdcall MSVCRT_what_exception(exception * _this); -bad_typeid * __stdcall MSVCRT_bad_typeid_copy_ctor(bad_typeid * _this, const bad_typeid * rhs); -bad_typeid * __stdcall MSVCRT_bad_typeid_ctor(bad_typeid * _this, const char * name); -bad_typeid * __stdcall MSVCRT_bad_typeid_default_ctor(bad_typeid * _this); -void __stdcall MSVCRT_bad_typeid_dtor(bad_typeid * _this); -bad_typeid * __stdcall MSVCRT_bad_typeid_opequals(bad_typeid * _this, const bad_typeid * rhs); -void * __stdcall MSVCRT_bad_typeid_vector_dtor(bad_typeid * _this, unsigned int flags); -void * __stdcall MSVCRT_bad_typeid_scalar_dtor(bad_typeid * _this, unsigned int flags); -__non_rtti_object * __stdcall MSVCRT___non_rtti_object_copy_ctor(__non_rtti_object * _this, const __non_rtti_object * rhs); -__non_rtti_object * __stdcall MSVCRT___non_rtti_object_ctor(__non_rtti_object * _this, const char * name); -void __stdcall MSVCRT___non_rtti_object_dtor(__non_rtti_object * _this); -__non_rtti_object * __stdcall MSVCRT___non_rtti_object_opequals(__non_rtti_object * _this, const __non_rtti_object *rhs); -void * __stdcall MSVCRT___non_rtti_object_vector_dtor(__non_rtti_object * _this, unsigned int flags); -void * __stdcall MSVCRT___non_rtti_object_scalar_dtor(__non_rtti_object * _this, unsigned int flags); -bad_cast * __stdcall MSVCRT_bad_cast_ctor(bad_cast * _this, const char ** name); -bad_cast * __stdcall MSVCRT_bad_cast_copy_ctor(bad_cast * _this, const bad_cast * rhs); -bad_cast * __stdcall MSVCRT_bad_cast_ctor_charptr(bad_cast * _this, const char * name); -bad_cast * __stdcall MSVCRT_bad_cast_default_ctor(bad_cast * _this); -void __stdcall MSVCRT_bad_cast_dtor(bad_cast * _this); -bad_cast * __stdcall MSVCRT_bad_cast_opequals(bad_cast * _this, const bad_cast * rhs); -void * __stdcall MSVCRT_bad_cast_vector_dtor(bad_cast * _this, unsigned int flags); -void * __stdcall MSVCRT_bad_cast_scalar_dtor(bad_cast * _this, unsigned int flags); -int __stdcall MSVCRT_type_info_opequals_equals(type_info * _this, const type_info * rhs); -int __stdcall MSVCRT_type_info_opnot_equals(type_info * _this, const type_info * rhs); -int __stdcall MSVCRT_type_info_before(type_info * _this, const type_info * rhs); -void __stdcall MSVCRT_type_info_dtor(type_info * _this); -const char * __stdcall MSVCRT_type_info_name(type_info * _this); -const char * __stdcall MSVCRT_type_info_raw_name(type_info * _this); -void * __stdcall MSVCRT_type_info_vector_dtor(type_info * _this, unsigned int flags); - -#define __ASM_VTABLE(name,funcs) -//void *MSVCRT_ ## name ##_vtable[] = +exception * __thiscall MSVCRT_exception_ctor(exception * _this, const char ** name); +exception * __thiscall MSVCRT_exception_ctor_noalloc(exception * _this, char ** name, int noalloc); +exception * __thiscall MSVCRT_exception_copy_ctor(exception * _this, const exception * rhs); +exception * __thiscall MSVCRT_exception_default_ctor(exception * _this); +void __thiscall MSVCRT_exception_dtor(exception * _this); +exception * __thiscall MSVCRT_exception_opequals(exception * _this, const exception * rhs); +void * __thiscall MSVCRT_exception_vector_dtor(exception * _this, unsigned int flags); +void * __thiscall MSVCRT_exception_scalar_dtor(exception * _this, unsigned int flags); +const char * __thiscall MSVCRT_what_exception(exception * _this); +bad_typeid * __thiscall MSVCRT_bad_typeid_copy_ctor(bad_typeid * _this, const bad_typeid * rhs); +bad_typeid * __thiscall MSVCRT_bad_typeid_ctor(bad_typeid * _this, const char * name); +bad_typeid * __thiscall MSVCRT_bad_typeid_default_ctor(bad_typeid * _this); +void __thiscall MSVCRT_bad_typeid_dtor(bad_typeid * _this); +bad_typeid * __thiscall MSVCRT_bad_typeid_opequals(bad_typeid * _this, const bad_typeid * rhs); +void * __thiscall MSVCRT_bad_typeid_vector_dtor(bad_typeid * _this, unsigned int flags); +void * __thiscall MSVCRT_bad_typeid_scalar_dtor(bad_typeid * _this, unsigned int flags); +__non_rtti_object * __thiscall MSVCRT___non_rtti_object_copy_ctor(__non_rtti_object * _this, const __non_rtti_object * rhs); +__non_rtti_object * __thiscall MSVCRT___non_rtti_object_ctor(__non_rtti_object * _this, const char * name); +void __thiscall MSVCRT___non_rtti_object_dtor(__non_rtti_object * _this); +__non_rtti_object * __thiscall MSVCRT___non_rtti_object_opequals(__non_rtti_object * _this, const __non_rtti_object *rhs); +void * __thiscall MSVCRT___non_rtti_object_vector_dtor(__non_rtti_object * _this, unsigned int flags); +void * __thiscall MSVCRT___non_rtti_object_scalar_dtor(__non_rtti_object * _this, unsigned int flags); +bad_cast * __thiscall MSVCRT_bad_cast_ctor(bad_cast * _this, const char ** name); +bad_cast * __thiscall MSVCRT_bad_cast_copy_ctor(bad_cast * _this, const bad_cast * rhs); +bad_cast * __thiscall MSVCRT_bad_cast_ctor_charptr(bad_cast * _this, const char * name); +bad_cast * __thiscall MSVCRT_bad_cast_default_ctor(bad_cast * _this); +void __thiscall MSVCRT_bad_cast_dtor(bad_cast * _this); +bad_cast * __thiscall MSVCRT_bad_cast_opequals(bad_cast * _this, const bad_cast * rhs); +void * __thiscall MSVCRT_bad_cast_vector_dtor(bad_cast * _this, unsigned int flags); +void * __thiscall MSVCRT_bad_cast_scalar_dtor(bad_cast * _this, unsigned int flags); +int __thiscall MSVCRT_type_info_opequals_equals(type_info * _this, const type_info * rhs); +int __thiscall MSVCRT_type_info_opnot_equals(type_info * _this, const type_info * rhs); +int __thiscall MSVCRT_type_info_before(type_info * _this, const type_info * rhs); +void __thiscall MSVCRT_type_info_dtor(type_info * _this); +const char * __thiscall MSVCRT_type_info_name(type_info * _this); +const char * __thiscall MSVCRT_type_info_raw_name(type_info * _this); +void * __thiscall MSVCRT_type_info_vector_dtor(type_info * _this, unsigned int flags); +#if _MSVCR_VER >= 80 +bad_alloc* __thiscall MSVCRT_bad_alloc_copy_ctor(bad_alloc* _this, const bad_alloc* rhs); +bad_alloc* __thiscall MSVCRT_bad_alloc_copy_ctor(bad_alloc* _this, const bad_alloc* rhs); +void __thiscall MSVCRT_bad_alloc_dtor(bad_alloc* _this); +#endif /* _MSVCR_VER >= 80 */ +#if _MSVCR_VER >= 100 +scheduler_resource_allocation_error* __thiscall scheduler_resource_allocation_error_ctor_name( + scheduler_resource_allocation_error* this, const char* name, HRESULT hr); +scheduler_resource_allocation_error* __thiscall scheduler_resource_allocation_error_ctor( + scheduler_resource_allocation_error* this, HRESULT hr); +scheduler_resource_allocation_error* __thiscall MSVCRT_scheduler_resource_allocation_error_copy_ctor( + scheduler_resource_allocation_error* this, + const scheduler_resource_allocation_error* rhs); +HRESULT __thiscall scheduler_resource_allocation_error_get_error_code( + const scheduler_resource_allocation_error* this); +void __thiscall MSVCRT_scheduler_resource_allocation_error_dtor( + scheduler_resource_allocation_error* this); +improper_lock* __thiscall improper_lock_ctor_str(improper_lock* this, const char* str); +improper_lock* __thiscall improper_lock_ctor(improper_lock* this); +improper_lock* __thiscall MSVCRT_improper_lock_copy_ctor(improper_lock* _this, const improper_lock* rhs); +void __thiscall MSVCRT_improper_lock_dtor(improper_lock* _this); +invalid_scheduler_policy_key* __thiscall invalid_scheduler_policy_key_ctor_str( + invalid_scheduler_policy_key* this, const char* str); +invalid_scheduler_policy_key* __thiscall invalid_scheduler_policy_key_ctor( + invalid_scheduler_policy_key* this); +invalid_scheduler_policy_key* __thiscall MSVCRT_invalid_scheduler_policy_key_copy_ctor( + invalid_scheduler_policy_key* _this, const invalid_scheduler_policy_key* rhs); +void __thiscall MSVCRT_invalid_scheduler_policy_key_dtor( + invalid_scheduler_policy_key* _this); +invalid_scheduler_policy_value* __thiscall invalid_scheduler_policy_value_ctor_str( + invalid_scheduler_policy_value* this, const char* str); +invalid_scheduler_policy_value* __thiscall invalid_scheduler_policy_value_ctor( + invalid_scheduler_policy_value* this); +invalid_scheduler_policy_value* __thiscall MSVCRT_invalid_scheduler_policy_value_copy_ctor( + invalid_scheduler_policy_value* _this, const invalid_scheduler_policy_value* rhs); +void __thiscall MSVCRT_invalid_scheduler_policy_value_dtor( + invalid_scheduler_policy_value* _this); +invalid_scheduler_policy_thread_specification* __thiscall invalid_scheduler_policy_thread_specification_ctor_str( + invalid_scheduler_policy_thread_specification* this, const char* str); +invalid_scheduler_policy_thread_specification* __thiscall invalid_scheduler_policy_thread_specification_ctor( + invalid_scheduler_policy_thread_specification* this); +invalid_scheduler_policy_thread_specification* __thiscall MSVCRT_invalid_scheduler_policy_thread_specification_copy_ctor( + invalid_scheduler_policy_thread_specification* _this, const invalid_scheduler_policy_thread_specification* rhs); +void __thiscall MSVCRT_invalid_scheduler_policy_thread_specification_dtor( + invalid_scheduler_policy_thread_specification* _this); +improper_scheduler_attach* __thiscall improper_scheduler_attach_ctor_str( + improper_scheduler_attach* this, const char* str); +improper_scheduler_attach* __thiscall improper_scheduler_attach_ctor( + improper_scheduler_attach* this); +improper_scheduler_attach* __thiscall MSVCRT_improper_scheduler_attach_copy_ctor( + improper_scheduler_attach* _this, const improper_scheduler_attach* rhs); +void __thiscall MSVCRT_improper_scheduler_attach_dtor( + improper_scheduler_attach* _this); +improper_scheduler_detach* __thiscall improper_scheduler_detach_ctor_str( + improper_scheduler_detach* this, const char* str); +improper_scheduler_detach* __thiscall improper_scheduler_detach_ctor( + improper_scheduler_detach* this); +improper_scheduler_detach* __thiscall MSVCRT_improper_scheduler_detach_copy_ctor( + improper_scheduler_detach* _this, const improper_scheduler_detach* rhs); +void __thiscall MSVCRT_improper_scheduler_detach_dtor( + improper_scheduler_detach* _this); +#endif diff --git a/sdk/lib/crt/wine/cpp.c b/sdk/lib/crt/wine/cpp.c new file mode 100644 index 00000000000..4b12b2dfbe1 --- /dev/null +++ b/sdk/lib/crt/wine/cpp.c @@ -0,0 +1,2189 @@ +/* + * msvcrt.dll C++ objects + * + * Copyright 2000 Jon Griffiths + * Copyright 2003, 2004 Alexandre Julliard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include <stdarg.h> + +#include "windef.h" +#include "winternl.h" +#include "wine/exception.h" +#include "wine/debug.h" +#include "msvcrt.h" +#include "cppexcept.h" +#include "mtdll.h" +#include "cxx.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msvcrt); + +struct __type_info_node +{ + void *memPtr; + struct __type_info_node* next; +}; + +typedef exception bad_cast; +typedef exception bad_typeid; +typedef exception __non_rtti_object; + +extern const vtable_ptr MSVCRT_exception_vtable; +extern const vtable_ptr MSVCRT_bad_typeid_vtable; +extern const vtable_ptr MSVCRT_bad_cast_vtable; +extern const vtable_ptr MSVCRT___non_rtti_object_vtable; +extern const vtable_ptr MSVCRT_type_info_vtable; + +/* get the vtable pointer for a C++ object */ +static inline const vtable_ptr *get_vtable( void *obj ) +{ + return *(const vtable_ptr **)obj; +} + +static inline const rtti_object_locator *get_obj_locator( void *cppobj ) +{ + const vtable_ptr *vtable = get_vtable( cppobj ); + return (const rtti_object_locator *)vtable[-1]; +} + +#ifndef __x86_64__ +static void dump_obj_locator( const rtti_object_locator *ptr ) +{ + int i; + const rtti_object_hierarchy *h = ptr->type_hierarchy; + + TRACE( "%p: sig=%08x base_offset=%08x flags=%08x type=%p %s hierarchy=%p\n", + ptr, ptr->signature, ptr->base_class_offset, ptr->flags, + ptr->type_descriptor, dbgstr_type_info(ptr->type_descriptor), ptr->type_hierarchy ); + TRACE( " hierarchy: sig=%08x attr=%08x len=%d base classes=%p\n", + h->signature, h->attributes, h->array_len, h->base_classes ); + for (i = 0; i < h->array_len; i++) + { + TRACE( " base class %p: num %d off %d,%d,%d attr %08x type %p %s\n", + h->base_classes->bases[i], + h->base_classes->bases[i]->num_base_classes, + h->base_classes->bases[i]->offsets.this_offset, + h->base_classes->bases[i]->offsets.vbase_descr, + h->base_classes->bases[i]->offsets.vbase_offset, + h->base_classes->bases[i]->attributes, + h->base_classes->bases[i]->type_descriptor, + dbgstr_type_info(h->base_classes->bases[i]->type_descriptor) ); + } +} + +#else + +static void dump_obj_locator( const rtti_object_locator *ptr ) +{ + int i; + char *base = ptr->signature == 0 ? RtlPcToFileHeader((void*)ptr, (void**)&base) : (char*)ptr - ptr->object_locator; + const rtti_object_hierarchy *h = (const rtti_object_hierarchy*)(base + ptr->type_hierarchy); + const type_info *type_descriptor = (const type_info*)(base + ptr->type_descriptor); + + TRACE( "%p: sig=%08x base_offset=%08x flags=%08x type=%p %s hierarchy=%p\n", + ptr, ptr->signature, ptr->base_class_offset, ptr->flags, + type_descriptor, dbgstr_type_info(type_descriptor), h ); + TRACE( " hierarchy: sig=%08x attr=%08x len=%d base classes=%p\n", + h->signature, h->attributes, h->array_len, base + h->base_classes ); + for (i = 0; i < h->array_len; i++) + { + const rtti_base_descriptor *bases = (rtti_base_descriptor*)(base + + ((const rtti_base_array*)(base + h->base_classes))->bases[i]); + + TRACE( " base class %p: num %d off %d,%d,%d attr %08x type %p %s\n", + bases, + bases->num_base_classes, + bases->offsets.this_offset, + bases->offsets.vbase_descr, + bases->offsets.vbase_offset, + bases->attributes, + base + bases->type_descriptor, + dbgstr_type_info((const type_info*)(base + bases->type_descriptor)) ); + } +} +#endif + +/* Internal common ctor for exception */ +static void EXCEPTION_ctor(exception *_this, const char** name) +{ + _this->vtable = &MSVCRT_exception_vtable; + if (*name) + { + unsigned int name_len = strlen(*name) + 1; + _this->name = MSVCRT_malloc(name_len); + memcpy(_this->name, *name, name_len); + _this->do_free = TRUE; + } + else + { + _this->name = NULL; + _this->do_free = FALSE; + } +} + +#ifdef __REACTOS__ +#include <internal/wine_msc.h> +#endif /* __REACTOS__ */ + +/****************************************************************** + * ??0exception@@QAE@ABQBD@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_exception_ctor,8) +exception * __thiscall MSVCRT_exception_ctor(exception * _this, const char ** name) +{ + TRACE("(%p,%s)\n", _this, *name); + EXCEPTION_ctor(_this, name); + return _this; +} + +/****************************************************************** + * ??0exception@@QAE@ABQBDH@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_exception_ctor_noalloc,12) +exception * __thiscall MSVCRT_exception_ctor_noalloc(exception * _this, char ** name, int noalloc) +{ + TRACE("(%p,%s)\n", _this, *name); + _this->vtable = &MSVCRT_exception_vtable; + _this->name = *name; + _this->do_free = FALSE; + return _this; +} + +/****************************************************************** + * ??0exception@@QAE@ABV0@@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_exception_copy_ctor,8) +exception * __thiscall MSVCRT_exception_copy_ctor(exception * _this, const exception * rhs) +{ + TRACE("(%p,%p)\n", _this, rhs); + + if (!rhs->do_free) + { + _this->vtable = &MSVCRT_exception_vtable; + _this->name = rhs->name; + _this->do_free = FALSE; + } + else + EXCEPTION_ctor(_this, (const char**)&rhs->name); + TRACE("name = %s\n", _this->name); + return _this; +} + +/****************************************************************** + * ??0exception@@QAE@XZ (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_exception_default_ctor,4) +exception * __thiscall MSVCRT_exception_default_ctor(exception * _this) +{ + static const char* empty = NULL; + + TRACE("(%p)\n", _this); + EXCEPTION_ctor(_this, &empty); + return _this; +} + +/****************************************************************** + * ??1exception@@UAE@XZ (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_exception_dtor,4) +void __thiscall MSVCRT_exception_dtor(exception * _this) +{ + TRACE("(%p)\n", _this); + _this->vtable = &MSVCRT_exception_vtable; + if (_this->do_free) MSVCRT_free(_this->name); +} + +/****************************************************************** + * ??4exception@@QAEAAV0@ABV0@@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_exception_opequals,8) +exception * __thiscall MSVCRT_exception_opequals(exception * _this, const exception * rhs) +{ + TRACE("(%p %p)\n", _this, rhs); + if (_this != rhs) + { + MSVCRT_exception_dtor(_this); + MSVCRT_exception_copy_ctor(_this, rhs); + } + TRACE("name = %s\n", _this->name); + return _this; +} + +/****************************************************************** + * ??_Eexception@@UAEPAXI@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_exception_vector_dtor,8) +void * __thiscall MSVCRT_exception_vector_dtor(exception * _this, unsigned int flags) +{ + TRACE("(%p %x)\n", _this, flags); + if (flags & 2) + { + /* we have an array, with the number of elements stored before the first object */ + INT_PTR i, *ptr = (INT_PTR *)_this - 1; + + for (i = *ptr - 1; i >= 0; i--) MSVCRT_exception_dtor(_this + i); + MSVCRT_operator_delete(ptr); + } + else + { + MSVCRT_exception_dtor(_this); + if (flags & 1) MSVCRT_operator_delete(_this); + } + return _this; +} + +/****************************************************************** + * ??_Gexception@@UAEPAXI@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_exception_scalar_dtor,8) +void * __thiscall MSVCRT_exception_scalar_dtor(exception * _this, unsigned int flags) +{ + TRACE("(%p %x)\n", _this, flags); + MSVCRT_exception_dtor(_this); + if (flags & 1) MSVCRT_operator_delete(_this); + return _this; +} + +/****************************************************************** + * ?what@exception@@UBEPBDXZ (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_what_exception,4) +const char * __thiscall MSVCRT_what_exception(exception * _this) +{ + TRACE("(%p) returning %s\n", _this, _this->name); + return _this->name ? _this->name : "Unknown exception"; +} + +/****************************************************************** + * ??0bad_typeid@@QAE@ABV0@@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_copy_ctor,8) +bad_typeid * __thiscall MSVCRT_bad_typeid_copy_ctor(bad_typeid * _this, const bad_typeid * rhs) +{ + TRACE("(%p %p)\n", _this, rhs); + MSVCRT_exception_copy_ctor(_this, rhs); + _this->vtable = &MSVCRT_bad_typeid_vtable; + return _this; +} + +/****************************************************************** + * ??0bad_typeid@@QAE@PBD@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_ctor,8) +bad_typeid * __thiscall MSVCRT_bad_typeid_ctor(bad_typeid * _this, const char * name) +{ + TRACE("(%p %s)\n", _this, name); + EXCEPTION_ctor(_this, &name); + _this->vtable = &MSVCRT_bad_typeid_vtable; + return _this; +} + +/****************************************************************** + * ??_Fbad_typeid@@QAEXXZ (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_default_ctor,4) +bad_typeid * __thiscall MSVCRT_bad_typeid_default_ctor(bad_typeid * _this) +{ + return MSVCRT_bad_typeid_ctor( _this, "bad typeid" ); +} + +/****************************************************************** + * ??1bad_typeid@@UAE@XZ (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_dtor,4) +void __thiscall MSVCRT_bad_typeid_dtor(bad_typeid * _this) +{ + TRACE("(%p)\n", _this); + MSVCRT_exception_dtor(_this); +} + +/****************************************************************** + * ??4bad_typeid@@QAEAAV0@ABV0@@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_opequals,8) +bad_typeid * __thiscall MSVCRT_bad_typeid_opequals(bad_typeid * _this, const bad_typeid * rhs) +{ + TRACE("(%p %p)\n", _this, rhs); + MSVCRT_exception_opequals(_this, rhs); + return _this; +} + +/****************************************************************** + * ??_Ebad_typeid@@UAEPAXI@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_vector_dtor,8) +void * __thiscall MSVCRT_bad_typeid_vector_dtor(bad_typeid * _this, unsigned int flags) +{ + TRACE("(%p %x)\n", _this, flags); + if (flags & 2) + { + /* we have an array, with the number of elements stored before the first object */ + INT_PTR i, *ptr = (INT_PTR *)_this - 1; + + for (i = *ptr - 1; i >= 0; i--) MSVCRT_bad_typeid_dtor(_this + i); + MSVCRT_operator_delete(ptr); + } + else + { + MSVCRT_bad_typeid_dtor(_this); + if (flags & 1) MSVCRT_operator_delete(_this); + } + return _this; +} + +/****************************************************************** + * ??_Gbad_typeid@@UAEPAXI@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_scalar_dtor,8) +void * __thiscall MSVCRT_bad_typeid_scalar_dtor(bad_typeid * _this, unsigned int flags) +{ + TRACE("(%p %x)\n", _this, flags); + MSVCRT_bad_typeid_dtor(_this); + if (flags & 1) MSVCRT_operator_delete(_this); + return _this; +} + +/****************************************************************** + * ??0__non_rtti_object@@QAE@ABV0@@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_copy_ctor,8) +__non_rtti_object * __thiscall MSVCRT___non_rtti_object_copy_ctor(__non_rtti_object * _this, + const __non_rtti_object * rhs) +{ + TRACE("(%p %p)\n", _this, rhs); + MSVCRT_bad_typeid_copy_ctor(_this, rhs); + _this->vtable = &MSVCRT___non_rtti_object_vtable; + return _this; +} + +/****************************************************************** + * ??0__non_rtti_object@@QAE@PBD@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_ctor,8) +__non_rtti_object * __thiscall MSVCRT___non_rtti_object_ctor(__non_rtti_object * _this, + const char * name) +{ + TRACE("(%p %s)\n", _this, name); + EXCEPTION_ctor(_this, &name); + _this->vtable = &MSVCRT___non_rtti_object_vtable; + return _this; +} + +/****************************************************************** + * ??1__non_rtti_object@@UAE@XZ (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_dtor,4) +void __thiscall MSVCRT___non_rtti_object_dtor(__non_rtti_object * _this) +{ + TRACE("(%p)\n", _this); + MSVCRT_bad_typeid_dtor(_this); +} + +/****************************************************************** + * ??4__non_rtti_object@@QAEAAV0@ABV0@@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_opequals,8) +__non_rtti_object * __thiscall MSVCRT___non_rtti_object_opequals(__non_rtti_object * _this, + const __non_rtti_object *rhs) +{ + TRACE("(%p %p)\n", _this, rhs); + MSVCRT_bad_typeid_opequals(_this, rhs); + return _this; +} + +/****************************************************************** + * ??_E__non_rtti_object@@UAEPAXI@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_vector_dtor,8) +void * __thiscall MSVCRT___non_rtti_object_vector_dtor(__non_rtti_object * _this, unsigned int flags) +{ + TRACE("(%p %x)\n", _this, flags); + if (flags & 2) + { + /* we have an array, with the number of elements stored before the first object */ + INT_PTR i, *ptr = (INT_PTR *)_this - 1; + + for (i = *ptr - 1; i >= 0; i--) MSVCRT___non_rtti_object_dtor(_this + i); + MSVCRT_operator_delete(ptr); + } + else + { + MSVCRT___non_rtti_object_dtor(_this); + if (flags & 1) MSVCRT_operator_delete(_this); + } + return _this; +} + +/****************************************************************** + * ??_G__non_rtti_object@@UAEPAXI@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_scalar_dtor,8) +void * __thiscall MSVCRT___non_rtti_object_scalar_dtor(__non_rtti_object * _this, unsigned int flags) +{ + TRACE("(%p %x)\n", _this, flags); + MSVCRT___non_rtti_object_dtor(_this); + if (flags & 1) MSVCRT_operator_delete(_this); + return _this; +} + +/****************************************************************** + * ??0bad_cast@@AAE@PBQBD@Z (MSVCRT.@) + * ??0bad_cast@@QAE@ABQBD@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_ctor,8) +bad_cast * __thiscall MSVCRT_bad_cast_ctor(bad_cast * _this, const char ** name) +{ + TRACE("(%p %s)\n", _this, *name); + EXCEPTION_ctor(_this, name); + _this->vtable = &MSVCRT_bad_cast_vtable; + return _this; +} + +/****************************************************************** + * ??0bad_cast@@QAE@ABV0@@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_copy_ctor,8) +bad_cast * __thiscall MSVCRT_bad_cast_copy_ctor(bad_cast * _this, const bad_cast * rhs) +{ + TRACE("(%p %p)\n", _this, rhs); + MSVCRT_exception_copy_ctor(_this, rhs); + _this->vtable = &MSVCRT_bad_cast_vtable; + return _this; +} + +/****************************************************************** + * ??0bad_cast@@QAE@PBD@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_ctor_charptr,8) +bad_cast * __thiscall MSVCRT_bad_cast_ctor_charptr(bad_cast * _this, const char * name) +{ + TRACE("(%p %s)\n", _this, name); + EXCEPTION_ctor(_this, &name); + _this->vtable = &MSVCRT_bad_cast_vtable; + return _this; +} + +/****************************************************************** + * ??_Fbad_cast@@QAEXXZ (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_default_ctor,4) +bad_cast * __thiscall MSVCRT_bad_cast_default_ctor(bad_cast * _this) +{ + return MSVCRT_bad_cast_ctor_charptr( _this, "bad cast" ); +} + +/****************************************************************** + * ??1bad_cast@@UAE@XZ (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_dtor,4) +void __thiscall MSVCRT_bad_cast_dtor(bad_cast * _this) +{ + TRACE("(%p)\n", _this); + MSVCRT_exception_dtor(_this); +} + +/****************************************************************** + * ??4bad_cast@@QAEAAV0@ABV0@@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_opequals,8) +bad_cast * __thiscall MSVCRT_bad_cast_opequals(bad_cast * _this, const bad_cast * rhs) +{ + TRACE("(%p %p)\n", _this, rhs); + MSVCRT_exception_opequals(_this, rhs); + return _this; +} + +/****************************************************************** + * ??_Ebad_cast@@UAEPAXI@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_vector_dtor,8) +void * __thiscall MSVCRT_bad_cast_vector_dtor(bad_cast * _this, unsigned int flags) +{ + TRACE("(%p %x)\n", _this, flags); + if (flags & 2) + { + /* we have an array, with the number of elements stored before the first object */ + INT_PTR i, *ptr = (INT_PTR *)_this - 1; + + for (i = *ptr - 1; i >= 0; i--) MSVCRT_bad_cast_dtor(_this + i); + MSVCRT_operator_delete(ptr); + } + else + { + MSVCRT_bad_cast_dtor(_this); + if (flags & 1) MSVCRT_operator_delete(_this); + } + return _this; +} + +/****************************************************************** + * ??_Gbad_cast@@UAEPAXI@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_scalar_dtor,8) +void * __thiscall MSVCRT_bad_cast_scalar_dtor(bad_cast * _this, unsigned int flags) +{ + TRACE("(%p %x)\n", _this, flags); + MSVCRT_bad_cast_dtor(_this); + if (flags & 1) MSVCRT_operator_delete(_this); + return _this; +} + +/****************************************************************** + * ??8type_info@@QBEHABV0@@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_opequals_equals,8) +int __thiscall MSVCRT_type_info_opequals_equals(type_info * _this, const type_info * rhs) +{ + int ret = !strcmp(_this->mangled + 1, rhs->mangled + 1); + TRACE("(%p %p) returning %d\n", _this, rhs, ret); + return ret; +} + +/****************************************************************** + * ??9type_info@@QBEHABV0@@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_opnot_equals,8) +int __thiscall MSVCRT_type_info_opnot_equals(type_info * _this, const type_info * rhs) +{ + int ret = !!strcmp(_this->mangled + 1, rhs->mangled + 1); + TRACE("(%p %p) returning %d\n", _this, rhs, ret); + return ret; +} + +/****************************************************************** + * ?before@type_info@@QBEHABV1@@Z (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_before,8) +int __thiscall MSVCRT_type_info_before(type_info * _this, const type_info * rhs) +{ + int ret = strcmp(_this->mangled + 1, rhs->mangled + 1) < 0; + TRACE("(%p %p) returning %d\n", _this, rhs, ret); + return ret; +} + +/****************************************************************** + * ??1type_info@@UAE@XZ (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_dtor,4) +void __thiscall MSVCRT_type_info_dtor(type_info * _this) +{ + TRACE("(%p)\n", _this); + MSVCRT_free(_this->name); +} + +/****************************************************************** + * ?name@type_info@@QBEPBDXZ (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_name,4) +const char * __thiscall MSVCRT_type_info_name(type_info * _this) +{ + if (!_this->name) + { + /* Create and set the demangled name */ + /* Note: mangled name in type_info struct always starts with a '.', while + * it isn't valid for mangled name. + * Is this '.' really part of the mangled name, or has it some other meaning ? + */ + char* name = __unDName(0, _this->mangled + 1, 0, + MSVCRT_malloc, MSVCRT_free, UNDNAME_NO_ARGUMENTS | UNDNAME_32_BIT_DECODE); + if (name) + { + unsigned int len = strlen(name); + + /* It seems _unDName may leave blanks at the end of the demangled name */ + while (len && name[--len] == ' ') + name[len] = '\0'; + + if (InterlockedCompareExchangePointer((void**)&_this->name, name, NULL)) + { + /* Another thread set this member since we checked above - use it */ + MSVCRT_free(name); + } + } + } + TRACE("(%p) returning %s\n", _this, _this->name); + return _this->name; +} + +/****************************************************************** + * ?raw_name@type_info@@QBEPBDXZ (MSVCRT.@) + */ +DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_raw_name,4) +const char * __thiscall MSVCRT_type_info_raw_name(type_info * _this) +{ + TRACE("(%p) returning %s\n", _this, _this->mangled); + return _this->mangled; +} + +/* Unexported */ +DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_vector_dtor,8) +void * __thiscall MSVCRT_type_info_vector_dtor(type_info * _this, unsigned int flags) +{ + TRACE("(%p %x)\n", _this, flags); + if (flags & 2) + { + /* we have an array, with the number of elements stored before the first object */ + INT_PTR i, *ptr = (INT_PTR *)_this - 1; + + for (i = *ptr - 1; i >= 0; i--) MSVCRT_type_info_dtor(_this + i); + MSVCRT_operator_delete(ptr); + } + else + { + MSVCRT_type_info_dtor(_this); + if (flags & 1) MSVCRT_operator_delete(_this); + } + return _this; +} + +#if _MSVCR_VER >= 80 + +typedef exception bad_alloc; +extern const vtable_ptr MSVCRT_bad_alloc_vtable; + +static void bad_alloc_ctor(bad_alloc *this, const char **name) +{ + MSVCRT_exception_ctor(this, name); + this->vtable = &MSVCRT_bad_alloc_vtable; +} + +/* bad_alloc class implementation */ +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_alloc_copy_ctor,8) +bad_alloc * __thiscall MSVCRT_bad_alloc_copy_ctor(bad_alloc * _this, const bad_alloc * rhs) +{ + TRACE("(%p %p)\n", _this, rhs); + MSVCRT_exception_copy_ctor(_this, rhs); + _this->vtable = &MSVCRT_bad_alloc_vtable; + return _this; +} + +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_alloc_dtor,4) +void __thiscall MSVCRT_bad_alloc_dtor(bad_alloc * _this) +{ + TRACE("(%p)\n", _this); + MSVCRT_exception_dtor(_this); +} + +#endif /* _MSVCR_VER >= 80 */ + +#if _MSVCR_VER >= 100 + +typedef struct { + exception e; + HRESULT hr; +} scheduler_resource_allocation_error; +extern const vtable_ptr MSVCRT_scheduler_resource_allocation_error_vtable; + +/* ??0scheduler_resource_allocation_error@Concurrency@@QAE@PBDJ@Z */ +/* ??0scheduler_resource_allocation_error@Concurrency@@QEAA@PEBDJ@Z */ +DEFINE_THISCALL_WRAPPER(scheduler_resource_allocation_error_ctor_name, 12) +scheduler_resource_allocation_error* __thiscall scheduler_resource_allocation_error_ctor_name( + scheduler_resource_allocation_error *this, const char *name, HRESULT hr) +{ + TRACE("(%p %s %x)\n", this, wine_dbgstr_a(name), hr); + MSVCRT_exception_ctor(&this->e, &name); + this->e.vtable = &MSVCRT_scheduler_resource_allocation_error_vtable; + this->hr = hr; + return this; +} + +/* ??0scheduler_resource_allocation_error@Concurrency@@QAE@J@Z */ +/* ??0scheduler_resource_allocation_error@Concurrency@@QEAA@J@Z */ +DEFINE_THISCALL_WRAPPER(scheduler_resource_allocation_error_ctor, 8) +scheduler_resource_allocation_error* __thiscall scheduler_resource_allocation_error_ctor( + scheduler_resource_allocation_error *this, HRESULT hr) +{ + return scheduler_resource_allocation_error_ctor_name(this, NULL, hr); +} + +DEFINE_THISCALL_WRAPPER(MSVCRT_scheduler_resource_allocation_error_copy_ctor,8) +scheduler_resource_allocation_error* __thiscall MSVCRT_scheduler_resource_allocation_error_copy_ctor( + scheduler_resource_allocation_error *this, + const scheduler_resource_allocation_error *rhs) +{ + TRACE("(%p,%p)\n", this, rhs); + + if (!rhs->e.do_free) + memcpy(this, rhs, sizeof(*this)); + else + scheduler_resource_allocation_error_ctor_name(this, rhs->e.name, rhs->hr); + return this; +} + +/* ?get_error_code@scheduler_resource_allocation_error@Concurrency@@QBEJXZ */ +/* ?get_error_code@scheduler_resource_allocation_error@Concurrency@@QEBAJXZ */ +DEFINE_THISCALL_WRAPPER(scheduler_resource_allocation_error_get_error_code, 4) +HRESULT __thiscall scheduler_resource_allocation_error_get_error_code( + const scheduler_resource_allocation_error *this) +{ + TRACE("(%p)\n", this); + return this->hr; +} + +DEFINE_THISCALL_WRAPPER(MSVCRT_scheduler_resource_allocation_error_dtor,4) +void __thiscall MSVCRT_scheduler_resource_allocation_error_dtor( + scheduler_resource_allocation_error * this) +{ + TRACE("(%p)\n", this); + MSVCRT_exception_dtor(&this->e); +} + +typedef exception improper_lock; +extern const vtable_ptr MSVCRT_improper_lock_vtable; + +/* ??0improper_lock@Concurrency@@QAE@PBD@Z */ +/* ??0improper_lock@Concurrency@@QEAA@PEBD@Z */ +DEFINE_THISCALL_WRAPPER(improper_lock_ctor_str, 8) +improper_lock* __thiscall improper_lock_ctor_str(improper_lock *this, const char *str) +{ + TRACE("(%p %p)\n", this, str); + MSVCRT_exception_ctor(this, &str); + this->vtable = &MSVCRT_improper_lock_vtable; + return this; +} + +/* ??0improper_lock@Concurrency@@QAE@XZ */ +/* ??0improper_lock@Concurrency@@QEAA@XZ */ +DEFINE_THISCALL_WRAPPER(improper_lock_ctor, 4) +improper_lock* __thiscall improper_lock_ctor(improper_lock *this) +{ + return improper_lock_ctor_str(this, NULL); +} + +DEFINE_THISCALL_WRAPPER(MSVCRT_improper_lock_copy_ctor,8) +improper_lock * __thiscall MSVCRT_improper_lock_copy_ctor(improper_lock * _this, const improper_lock * rhs) +{ + TRACE("(%p %p)\n", _this, rhs); + MSVCRT_exception_copy_ctor(_this, rhs); + _this->vtable = &MSVCRT_improper_lock_vtable; + return _this; +} + +DEFINE_THISCALL_WRAPPER(MSVCRT_improper_lock_dtor,4) +void __thiscall MSVCRT_improper_lock_dtor(improper_lock * _this) +{ + TRACE("(%p)\n", _this); + MSVCRT_exception_dtor(_this); +} + +typedef exception invalid_scheduler_policy_key; +extern const vtable_ptr MSVCRT_invalid_scheduler_policy_key_vtable; + +/* ??0invalid_scheduler_policy_key@Concurrency@@QAE@PBD@Z */ +/* ??0invalid_scheduler_policy_key@Concurrency@@QEAA@PEBD@Z */ +DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_key_ctor_str, 8) +invalid_scheduler_policy_key* __thiscall invalid_scheduler_policy_key_ctor_str( + invalid_scheduler_policy_key *this, const char *str) +{ + TRACE("(%p %p)\n", this, str); + MSVCRT_exception_ctor(this, &str); + this->vtable = &MSVCRT_invalid_scheduler_policy_key_vtable; + return this; +} + +/* ??0invalid_scheduler_policy_key@Concurrency@@QAE@XZ */ +/* ??0invalid_scheduler_policy_key@Concurrency@@QEAA@XZ */ +DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_key_ctor, 4) +invalid_scheduler_policy_key* __thiscall invalid_scheduler_policy_key_ctor( + invalid_scheduler_policy_key *this) +{ + return invalid_scheduler_policy_key_ctor_str(this, NULL); +} + +DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_key_copy_ctor,8) +invalid_scheduler_policy_key * __thiscall MSVCRT_invalid_scheduler_policy_key_copy_ctor( + invalid_scheduler_policy_key * _this, const invalid_scheduler_policy_key * rhs) +{ + TRACE("(%p %p)\n", _this, rhs); + MSVCRT_exception_copy_ctor(_this, rhs); + _this->vtable = &MSVCRT_invalid_scheduler_policy_key_vtable; + return _this; +} + +DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_key_dtor,4) +void __thiscall MSVCRT_invalid_scheduler_policy_key_dtor( + invalid_scheduler_policy_key * _this) +{ + TRACE("(%p)\n", _this); + MSVCRT_exception_dtor(_this); +} + +typedef exception invalid_scheduler_policy_value; +extern const vtable_ptr MSVCRT_invalid_scheduler_policy_value_vtable; + +/* ??0invalid_scheduler_policy_value@Concurrency@@QAE@PBD@Z */ +/* ??0invalid_scheduler_policy_value@Concurrency@@QEAA@PEBD@Z */ +DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_value_ctor_str, 8) +invalid_scheduler_policy_value* __thiscall invalid_scheduler_policy_value_ctor_str( + invalid_scheduler_policy_value *this, const char *str) +{ + TRACE("(%p %p)\n", this, str); + MSVCRT_exception_ctor(this, &str); + this->vtable = &MSVCRT_invalid_scheduler_policy_value_vtable; + return this; +} + +/* ??0invalid_scheduler_policy_value@Concurrency@@QAE@XZ */ +/* ??0invalid_scheduler_policy_value@Concurrency@@QEAA@XZ */ +DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_value_ctor, 4) +invalid_scheduler_policy_value* __thiscall invalid_scheduler_policy_value_ctor( + invalid_scheduler_policy_value *this) +{ + return invalid_scheduler_policy_value_ctor_str(this, NULL); +} + +DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_value_copy_ctor,8) +invalid_scheduler_policy_value * __thiscall MSVCRT_invalid_scheduler_policy_value_copy_ctor( + invalid_scheduler_policy_value * _this, const invalid_scheduler_policy_value * rhs) +{ + TRACE("(%p %p)\n", _this, rhs); + MSVCRT_exception_copy_ctor(_this, rhs); + _this->vtable = &MSVCRT_invalid_scheduler_policy_value_vtable; + return _this; +} + +DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_value_dtor,4) +void __thiscall MSVCRT_invalid_scheduler_policy_value_dtor( + invalid_scheduler_policy_value * _this) +{ + TRACE("(%p)\n", _this); + MSVCRT_exception_dtor(_this); +} + +typedef exception invalid_scheduler_policy_thread_specification; +extern const vtable_ptr MSVCRT_invalid_scheduler_policy_thread_specification_vtable; + +/* ??0invalid_scheduler_policy_thread_specification@Concurrency@@QAE@PBD@Z */ +/* ??0invalid_scheduler_policy_thread_specification@Concurrency@@QEAA@PEBD@Z */ +DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_thread_specification_ctor_str, 8) +invalid_scheduler_policy_thread_specification* __thiscall invalid_scheduler_policy_thread_specification_ctor_str( + invalid_scheduler_policy_thread_specification *this, const char *str) +{ + TRACE("(%p %p)\n", this, str); + MSVCRT_exception_ctor(this, &str); + this->vtable = &MSVCRT_invalid_scheduler_policy_thread_specification_vtable; + return this; +} + +/* ??0invalid_scheduler_policy_thread_specification@Concurrency@@QAE@XZ */ +/* ??0invalid_scheduler_policy_thread_specification@Concurrency@@QEAA@XZ */ +DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_thread_specification_ctor, 4) +invalid_scheduler_policy_thread_specification* __thiscall invalid_scheduler_policy_thread_specification_ctor( + invalid_scheduler_policy_thread_specification *this) +{ + return invalid_scheduler_policy_thread_specification_ctor_str(this, NULL); +} + +DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_thread_specification_copy_ctor,8) +invalid_scheduler_policy_thread_specification * __thiscall MSVCRT_invalid_scheduler_policy_thread_specification_copy_ctor( + invalid_scheduler_policy_thread_specification * _this, const invalid_scheduler_policy_thread_specification * rhs) +{ + TRACE("(%p %p)\n", _this, rhs); + MSVCRT_exception_copy_ctor(_this, rhs); + _this->vtable = &MSVCRT_invalid_scheduler_policy_thread_specification_vtable; + return _this; +} + +DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_thread_specification_dtor,4) +void __thiscall MSVCRT_invalid_scheduler_policy_thread_specification_dtor( + invalid_scheduler_policy_thread_specification * _this) +{ + TRACE("(%p)\n", _this); + MSVCRT_exception_dtor(_this); +} + +typedef exception improper_scheduler_attach; +extern const vtable_ptr MSVCRT_improper_scheduler_attach_vtable; + +/* ??0improper_scheduler_attach@Concurrency@@QAE@PBD@Z */ +/* ??0improper_scheduler_attach@Concurrency@@QEAA@PEBD@Z */ +DEFINE_THISCALL_WRAPPER(improper_scheduler_attach_ctor_str, 8) +improper_scheduler_attach* __thiscall improper_scheduler_attach_ctor_str( + improper_scheduler_attach *this, const char *str) +{ + TRACE("(%p %p)\n", this, str); + MSVCRT_exception_ctor(this, &str); + this->vtable = &MSVCRT_improper_scheduler_attach_vtable; + return this; +} + +/* ??0improper_scheduler_attach@Concurrency@@QAE@XZ */ +/* ??0improper_scheduler_attach@Concurrency@@QEAA@XZ */ +DEFINE_THISCALL_WRAPPER(improper_scheduler_attach_ctor, 4) +improper_scheduler_attach* __thiscall improper_scheduler_attach_ctor( + improper_scheduler_attach *this) +{ + return improper_scheduler_attach_ctor_str(this, NULL); +} + +DEFINE_THISCALL_WRAPPER(MSVCRT_improper_scheduler_attach_copy_ctor,8) +improper_scheduler_attach * __thiscall MSVCRT_improper_scheduler_attach_copy_ctor( + improper_scheduler_attach * _this, const improper_scheduler_attach * rhs) +{ + TRACE("(%p %p)\n", _this, rhs); + MSVCRT_exception_copy_ctor(_this, rhs); + _this->vtable = &MSVCRT_improper_scheduler_attach_vtable; + return _this; +} + +DEFINE_THISCALL_WRAPPER(MSVCRT_improper_scheduler_attach_dtor,4) +void __thiscall MSVCRT_improper_scheduler_attach_dtor( + improper_scheduler_attach * _this) +{ + TRACE("(%p)\n", _this); + MSVCRT_exception_dtor(_this); +} + +typedef exception improper_scheduler_detach; +extern const vtable_ptr MSVCRT_improper_scheduler_detach_vtable; + +/* ??0improper_scheduler_detach@Concurrency@@QAE@PBD@Z */ +/* ??0improper_scheduler_detach@Concurrency@@QEAA@PEBD@Z */ +DEFINE_THISCALL_WRAPPER(improper_scheduler_detach_ctor_str, 8) +improper_scheduler_detach* __thiscall improper_scheduler_detach_ctor_str( + improper_scheduler_detach *this, const char *str) +{ + TRACE("(%p %p)\n", this, str); + MSVCRT_exception_ctor(this, &str); + this->vtable = &MSVCRT_improper_scheduler_detach_vtable; + return this; +} + +/* ??0improper_scheduler_detach@Concurrency@@QAE@XZ */ +/* ??0improper_scheduler_detach@Concurrency@@QEAA@XZ */ +DEFINE_THISCALL_WRAPPER(improper_scheduler_detach_ctor, 4) +improper_scheduler_detach* __thiscall improper_scheduler_detach_ctor( + improper_scheduler_detach *this) +{ + return improper_scheduler_detach_ctor_str(this, NULL); +} + +DEFINE_THISCALL_WRAPPER(MSVCRT_improper_scheduler_detach_copy_ctor,8) +improper_scheduler_detach * __thiscall MSVCRT_improper_scheduler_detach_copy_ctor( + improper_scheduler_detach * _this, const improper_scheduler_detach * rhs) +{ + TRACE("(%p %p)\n", _this, rhs); + MSVCRT_exception_copy_ctor(_this, rhs); + _this->vtable = &MSVCRT_improper_scheduler_detach_vtable; + return _this; +} + +DEFINE_THISCALL_WRAPPER(MSVCRT_improper_scheduler_detach_dtor,4) +void __thiscall MSVCRT_improper_scheduler_detach_dtor( + improper_scheduler_detach * _this) +{ + TRACE("(%p)\n", _this); + MSVCRT_exception_dtor(_this); +} + +#endif /* _MSVCR_VER >= 100 */ + +#ifndef _MSC_VER +#ifndef __GNUC__ +void __asm_dummy_vtables(void) { +#endif + +__ASM_VTABLE(type_info, + VTABLE_ADD_FUNC(MSVCRT_type_info_vector_dtor)); +__ASM_VTABLE(exception, + VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) + VTABLE_ADD_FUNC(MSVCRT_what_exception)); +#if _MSVCR_VER >= 80 +__ASM_VTABLE(exception_old, + VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) + VTABLE_ADD_FUNC(MSVCRT_what_exception)); +__ASM_VTABLE(bad_alloc, + VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) + VTABLE_ADD_FUNC(MSVCRT_what_exception)); +#endif +__ASM_VTABLE(bad_typeid, + VTABLE_ADD_FUNC(MSVCRT_bad_typeid_vector_dtor) + VTABLE_ADD_FUNC(MSVCRT_what_exception)); +__ASM_VTABLE(bad_cast, + VTABLE_ADD_FUNC(MSVCRT_bad_cast_vector_dtor) + VTABLE_ADD_FUNC(MSVCRT_what_exception)); +__ASM_VTABLE(__non_rtti_object, + VTABLE_ADD_FUNC(MSVCRT___non_rtti_object_vector_dtor) + VTABLE_ADD_FUNC(MSVCRT_what_exception)); +#if _MSVCR_VER >= 100 +__ASM_VTABLE(scheduler_resource_allocation_error, + VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) + VTABLE_ADD_FUNC(MSVCRT_what_exception)); +__ASM_VTABLE(improper_lock, + VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) + VTABLE_ADD_FUNC(MSVCRT_what_exception)); +__ASM_VTABLE(invalid_scheduler_policy_key, + VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) + VTABLE_ADD_FUNC(MSVCRT_what_exception)); +__ASM_VTABLE(invalid_scheduler_policy_value, + VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) + VTABLE_ADD_FUNC(MSVCRT_what_exception)); +__ASM_VTABLE(invalid_scheduler_policy_thread_specification, + VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) + VTABLE_ADD_FUNC(MSVCRT_what_exception)); +__ASM_VTABLE(improper_scheduler_attach, + VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) + VTABLE_ADD_FUNC(MSVCRT_what_exception)); +__ASM_VTABLE(improper_scheduler_detach, + VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) + VTABLE_ADD_FUNC(MSVCRT_what_exception)); +#endif + +#ifndef __GNUC__ +} +#endif +#endif /* !_MSC_VER */ + +DEFINE_RTTI_DATA0( type_info, 0, ".?AVtype_info@@" ) +#if _MSVCR_VER >= 80 +DEFINE_RTTI_DATA0( exception, 0, ".?AVexception@std@@" ) +DEFINE_RTTI_DATA0( exception_old, 0, ".?AVexception@@" ) +DEFINE_RTTI_DATA1( bad_typeid, 0, &exception_rtti_base_descriptor, ".?AVbad_typeid@std@@" ) +DEFINE_RTTI_DATA1( bad_cast, 0, &exception_rtti_base_descriptor, ".?AVbad_cast@std@@" ) +DEFINE_RTTI_DATA2( __non_rtti_object, 0, &bad_typeid_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AV__non_rtti_object@std@@" ) +DEFINE_RTTI_DATA1( bad_alloc, 0, &exception_rtti_base_descriptor, ".?AVbad_alloc@std@@" ) +#else +DEFINE_RTTI_DATA0( exception, 0, ".?AVexception@@" ) +DEFINE_RTTI_DATA1( bad_typeid, 0, &exception_rtti_base_descriptor, ".?AVbad_typeid@@" ) +DEFINE_RTTI_DATA1( bad_cast, 0, &exception_rtti_base_descriptor, ".?AVbad_cast@@" ) +DEFINE_RTTI_DATA2( __non_rtti_object, 0, &bad_typeid_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AV__non_rtti_object@@" ) +#endif +#if _MSVCR_VER >= 100 +DEFINE_RTTI_DATA1(scheduler_resource_allocation_error, 0, &exception_rtti_base_descriptor, + ".?AVscheduler_resource_allocation_error@Concurrency@@") +DEFINE_RTTI_DATA1(improper_lock, 0, &exception_rtti_base_descriptor, ".?AVimproper_lock@Concurrency@@" ) +DEFINE_RTTI_DATA1(invalid_scheduler_policy_key, 0, &exception_rtti_base_descriptor, + ".?AVinvalid_scheduler_policy_key@Concurrency@@" ) +DEFINE_RTTI_DATA1(invalid_scheduler_policy_value, 0, &exception_rtti_base_descriptor, + ".?AVinvalid_scheduler_policy_value@Concurrency@@" ) +DEFINE_RTTI_DATA1(invalid_scheduler_policy_thread_specification, 0, &exception_rtti_base_descriptor, + ".?AVinvalid_scheduler_policy_thread_specification@Concurrency@@" ) +DEFINE_RTTI_DATA1(improper_scheduler_attach, 0, &exception_rtti_base_descriptor, + ".?AVimproper_scheduler_attach@Concurrency@@" ) +DEFINE_RTTI_DATA1(improper_scheduler_detach, 0, &exception_rtti_base_descriptor, + ".?AVimproper_scheduler_detach@Concurrency@@" ) +#endif + +DEFINE_EXCEPTION_TYPE_INFO( exception, 0, NULL, NULL ) +DEFINE_EXCEPTION_TYPE_INFO( bad_typeid, 1, &exception_cxx_type_info, NULL ) +DEFINE_EXCEPTION_TYPE_INFO( bad_cast, 1, &exception_cxx_type_info, NULL ) +DEFINE_EXCEPTION_TYPE_INFO( __non_rtti_object, 2, &bad_typeid_cxx_type_info, &exception_cxx_type_info ) +#if _MSVCR_VER >= 80 +DEFINE_EXCEPTION_TYPE_INFO( bad_alloc, 1, &exception_cxx_type_info, NULL ) +#endif +#if _MSVCR_VER >= 100 +DEFINE_EXCEPTION_TYPE_INFO(scheduler_resource_allocation_error, 1, &exception_cxx_type_info, NULL) +DEFINE_EXCEPTION_TYPE_INFO(improper_lock, 1, &exception_cxx_type_info, NULL) +DEFINE_EXCEPTION_TYPE_INFO(invalid_scheduler_policy_key, 1, &exception_cxx_type_info, NULL) +DEFINE_EXCEPTION_TYPE_INFO(invalid_scheduler_policy_value, 1, &exception_cxx_type_info, NULL) +DEFINE_EXCEPTION_TYPE_INFO(invalid_scheduler_policy_thread_specification, 1, &exception_cxx_type_info, NULL) +DEFINE_EXCEPTION_TYPE_INFO(improper_scheduler_attach, 1, &exception_cxx_type_info, NULL) +DEFINE_EXCEPTION_TYPE_INFO(improper_scheduler_detach, 1, &exception_cxx_type_info, NULL) +#endif + +void msvcrt_init_exception(void *base) +{ +#ifdef __x86_64__ + init_type_info_rtti(base); + init_exception_rtti(base); +#if _MSVCR_VER >= 80 + init_exception_old_rtti(base); + init_bad_alloc_rtti(base); +#endif + init_bad_typeid_rtti(base); + init_bad_cast_rtti(base); + init___non_rtti_object_rtti(base); +#if _MSVCR_VER >= 100 + init_scheduler_resource_allocation_error_rtti(base); + init_improper_lock_rtti(base); + init_invalid_scheduler_policy_key_rtti(base); + init_invalid_scheduler_policy_value_rtti(base); + init_invalid_scheduler_policy_thread_specification_rtti(base); + init_improper_scheduler_attach_rtti(base); + init_improper_scheduler_detach_rtti(base); +#endif + + init_exception_cxx(base); + init_bad_typeid_cxx(base); + init_bad_cast_cxx(base); + init___non_rtti_object_cxx(base); +#if _MSVCR_VER >= 80 + init_bad_alloc_cxx(base); +#endif +#if _MSVCR_VER >= 100 + init_scheduler_resource_allocation_error_cxx(base); + init_improper_lock_cxx(base); + init_invalid_scheduler_policy_key_cxx(base); + init_invalid_scheduler_policy_value_cxx(base); + init_invalid_scheduler_policy_thread_specification_cxx(base); + init_improper_scheduler_attach_cxx(base); + init_improper_scheduler_detach_cxx(base); +#endif +#endif +} + +#if _MSVCR_VER >= 80 +void throw_exception(exception_type et, HRESULT hr, const char *str) +{ + switch(et) { + case EXCEPTION_BAD_ALLOC: { + bad_alloc e; + bad_alloc_ctor(&e, &str); + _CxxThrowException(&e, &bad_alloc_exception_type); + } +#if _MSVCR_VER >= 100 + case EXCEPTION_SCHEDULER_RESOURCE_ALLOCATION_ERROR: { + scheduler_resource_allocation_error e; + scheduler_resource_allocation_error_ctor_name(&e, str, hr); + _CxxThrowException(&e.e, &scheduler_resource_allocation_error_exception_type); + } + case EXCEPTION_IMPROPER_LOCK: { + improper_lock e; + improper_lock_ctor_str(&e, str); + _CxxThrowException(&e, &improper_lock_exception_type); + } + case EXCEPTION_INVALID_SCHEDULER_POLICY_KEY: { + invalid_scheduler_policy_key e; + invalid_scheduler_policy_key_ctor_str(&e, str); + _CxxThrowException(&e, &invalid_scheduler_policy_key_exception_type); + } + case EXCEPTION_INVALID_SCHEDULER_POLICY_VALUE: { + invalid_scheduler_policy_value e; + invalid_scheduler_policy_value_ctor_str(&e, str); + _CxxThrowException(&e, &invalid_scheduler_policy_value_exception_type); + } + case EXCEPTION_INVALID_SCHEDULER_POLICY_THREAD_SPECIFICATION: { + invalid_scheduler_policy_thread_specification e; + invalid_scheduler_policy_thread_specification_ctor_str(&e, str); + _CxxThrowException(&e, &invalid_scheduler_policy_thread_specification_exception_type); + } + case EXCEPTION_IMPROPER_SCHEDULER_ATTACH: { + improper_scheduler_attach e; + improper_scheduler_attach_ctor_str(&e, str); + _CxxThrowException(&e, &improper_scheduler_attach_exception_type); + } + case EXCEPTION_IMPROPER_SCHEDULER_DETACH: { + improper_scheduler_detach e; + improper_scheduler_detach_ctor_str(&e, str); + _CxxThrowException(&e, &improper_scheduler_detach_exception_type); + } +#endif + } +} +#endif + +/****************************************************************** + * ?set_terminate@@YAP6AXXZP6AXXZ@Z (MSVCRT.@) + * + * Install a handler to be called when terminate() is called. + * + * PARAMS + * func [I] Handler function to install + * + * RETURNS + * The previously installed handler function, if any. + */ +MSVCRT_terminate_function CDECL MSVCRT_set_terminate(MSVCRT_terminate_function func) +{ + thread_data_t *data = msvcrt_get_thread_data(); + MSVCRT_terminate_function previous = data->terminate_handler; + TRACE("(%p) returning %p\n",func,previous); + data->terminate_handler = func; + return previous; +} + +/****************************************************************** + * _get_terminate (MSVCRT.@) + */ +MSVCRT_terminate_function CDECL MSVCRT__get_terminate(void) +{ + thread_data_t *data = msvcrt_get_thread_data(); + TRACE("returning %p\n", data->terminate_handler); + return data->terminate_handler; +} + +/****************************************************************** + * ?set_unexpected@@YAP6AXXZP6AXXZ@Z (MSVCRT.@) + * + * Install a handler to be called when unexpected() is called. + * + * PARAMS + * func [I] Handler function to install + * + * RETURNS + * The previously installed handler function, if any. + */ +MSVCRT_unexpected_function CDECL MSVCRT_set_unexpected(MSVCRT_unexpected_function func) +{ + thread_data_t *data = msvcrt_get_thread_data(); + MSVCRT_unexpected_function previous = data->unexpected_handler; + TRACE("(%p) returning %p\n",func,previous); + data->unexpected_handler = func; + return previous; +} + +/****************************************************************** + * _get_unexpected (MSVCRT.@) + */ +MSVCRT_unexpected_function CDECL MSVCRT__get_unexpected(void) +{ + thread_data_t *data = msvcrt_get_thread_data(); + TRACE("returning %p\n", data->unexpected_handler); + return data->unexpected_handler; +} + +/****************************************************************** + * ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z (MSVCRT.@) + */ +MSVCRT__se_translator_function CDECL MSVCRT__set_se_translator(MSVCRT__se_translator_function func) +{ + thread_data_t *data = msvcrt_get_thread_data(); + MSVCRT__se_translator_function previous = data->se_translator; + TRACE("(%p) returning %p\n",func,previous); + data->se_translator = func; + return previous; +} + +/****************************************************************** + * ?terminate@@YAXXZ (MSVCRT.@) + * + * Default handler for an unhandled exception. + * + * PARAMS + * None. + * + * RETURNS + * This function does not return. Either control resumes from any + * handler installed by calling set_terminate(), or (by default) abort() + * is called. + */ +void CDECL MSVCRT_terminate(void) +{ + thread_data_t *data = msvcrt_get_thread_data(); + if (data->terminate_handler) data->terminate_handler(); + MSVCRT_abort(); +} + +/****************************************************************** + * ?unexpected@@YAXXZ (MSVCRT.@) + */ +void CDECL MSVCRT_unexpected(void) +{ + thread_data_t *data = msvcrt_get_thread_data(); + if (data->unexpected_handler) data->unexpected_handler(); + MSVCRT_terminate(); +} + + +/****************************************************************** + * __RTtypeid (MSVCRT.@) + * + * Retrieve the Run Time Type Information (RTTI) for a C++ object. + * + * PARAMS + * cppobj [I] C++ object to get type information for. + * + * RETURNS + * Success: A type_info object describing cppobj. + * Failure: If the object to be cast has no RTTI, a __non_rtti_object + * exception is thrown. If cppobj is NULL, a bad_typeid exception + * is thrown. In either case, this function does not return. + * + * NOTES + * This function is usually called by compiler generated code as a result + * of using one of the C++ dynamic cast statements. + */ +#ifndef __x86_64__ +const type_info* CDECL MSVCRT___RTtypeid(void *cppobj) +{ + const type_info *ret; + + if (!cppobj) + { + bad_typeid e; + MSVCRT_bad_typeid_ctor( &e, "Attempted a typeid of NULL pointer!" ); + _CxxThrowException( &e, &bad_typeid_exception_type ); + return NULL; + } + + __TRY + { + const rtti_object_locator *obj_locator = get_obj_locator( cppobj ); + ret = obj_locator->type_descriptor; + } + __EXCEPT_PAGE_FAULT + { + __non_rtti_object e; + MSVCRT___non_rtti_object_ctor( &e, "Bad read pointer - no RTTI data!" ); + _CxxThrowException( &e, &__non_rtti_object_exception_type ); + return NULL; + } + __ENDTRY + return ret; +} + +#else + +const type_info* CDECL MSVCRT___RTtypeid(void *cppobj) +{ + const type_info *ret; + + if (!cppobj) + { + bad_typeid e; + MSVCRT_bad_typeid_ctor( &e, "Attempted a typeid of NULL pointer!" ); + _CxxThrowException( &e, &bad_typeid_exception_type ); + return NULL; + } + + __TRY + { + const rtti_object_locator *obj_locator = get_obj_locator( cppobj ); + char *base; + + if(obj_locator->signature == 0) + base = RtlPcToFileHeader((void*)obj_locator, (void**)&base); + else + base = (char*)obj_locator - obj_locator->object_locator; + + ret = (type_info*)(base + obj_locator->type_descriptor); + } + __EXCEPT_PAGE_FAULT + { + __non_rtti_object e; + MSVCRT___non_rtti_object_ctor( &e, "Bad read pointer - no RTTI data!" ); + _CxxThrowException( &e, &__non_rtti_object_exception_type ); + return NULL; + } + __ENDTRY + return ret; +} +#endif + +/****************************************************************** + * __RTDynamicCast (MSVCRT.@) + * + * Dynamically cast a C++ object to one of its base classes. + * + * PARAMS + * cppobj [I] Any C++ object to cast + * unknown [I] Reserved, set to 0 + * src [I] type_info object describing cppobj + * dst [I] type_info object describing the base class to cast to + * do_throw [I] TRUE = throw an exception if the cast fails, FALSE = don't + * + * RETURNS + * Success: The address of cppobj, cast to the object described by dst. + * Failure: NULL, If the object to be cast has no RTTI, or dst is not a + * valid cast for cppobj. If do_throw is TRUE, a bad_cast exception + * is thrown and this function does not return. + * + * NOTES + * This function is usually called by compiler generated code as a result + * of using one of the C++ dynamic cast statements. + */ +#ifndef __x86_64__ +void* CDECL MSVCRT___RTDynamicCast(void *cppobj, int unknown, + type_info *src, type_info *dst, + int do_throw) +{ + void *ret; + + if (!cppobj) return NULL; + + TRACE("obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)\n", + cppobj, unknown, src, dbgstr_type_info(src), dst, dbgstr_type_info(dst), do_throw); + + /* To cast an object at runtime: + * 1.Find out the true type of the object from the typeinfo at vtable[-1] + * 2.Search for the destination type in the class hierarchy + * 3.If destination type is found, return base object address + dest offset + * Otherwise, fail the cast + * + * FIXME: the unknown parameter doesn't seem to be used for anything + */ + __TRY + { + int i; + const rtti_object_locator *obj_locator = get_obj_locator( cppobj ); + const rtti_object_hierarchy *obj_bases = obj_locator->type_hierarchy; + const rtti_base_descriptor * const* base_desc = obj_bases->base_classes->bases; + + if (TRACE_ON(msvcrt)) dump_obj_locator(obj_locator); + + ret = NULL; + for (i = 0; i < obj_bases->array_len; i++) + { + const type_info *typ = base_desc[i]->type_descriptor; + + if (!strcmp(typ->mangled, dst->mangled)) + { + /* compute the correct this pointer for that base class */ + void *this_ptr = (char *)cppobj - obj_locator->base_class_offset; + ret = get_this_pointer( &base_desc[i]->offsets, this_ptr ); + break; + } + } + /* VC++ sets do_throw to 1 when the result of a dynamic_cast is assigned + * to a reference, since references cannot be NULL. + */ + if (!ret && do_throw) + { + const char *msg = "Bad dynamic_cast!"; + bad_cast e; + MSVCRT_bad_cast_ctor( &e, &msg ); + _CxxThrowException( &e, &bad_cast_exception_type ); + } + } + __EXCEPT_PAGE_FAULT + { + __non_rtti_object e; + MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" ); + _CxxThrowException( &e, &__non_rtti_object_exception_type ); + return NULL; + } + __ENDTRY + return ret; +} + +#else + +void* CDECL MSVCRT___RTDynamicCast(void *cppobj, int unknown, + type_info *src, type_info *dst, + int do_throw) +{ + void *ret; + + if (!cppobj) return NULL; + + TRACE("obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)\n", + cppobj, unknown, src, dbgstr_type_info(src), dst, dbgstr_type_info(dst), do_throw); + + __TRY + { + int i; + const rtti_object_locator *obj_locator = get_obj_locator( cppobj ); + const rtti_object_hierarchy *obj_bases; + const rtti_base_array *base_array; + char *base; + + if (TRACE_ON(msvcrt)) dump_obj_locator(obj_locator); + + if(obj_locator->signature == 0) + base = RtlPcToFileHeader((void*)obj_locator, (void**)&base); + else + base = (char*)obj_locator - obj_locator->object_locator; + + obj_bases = (const rtti_object_hierarchy*)(base + obj_locator->type_hierarchy); + base_array = (const rtti_base_array*)(base + obj_bases->base_classes); + + ret = NULL; + for (i = 0; i < obj_bases->array_len; i++) + { + const rtti_base_descriptor *base_desc = (const rtti_base_descriptor*)(base + base_array->bases[i]); + const type_info *typ = (const type_info*)(base + base_desc->type_descriptor); + + if (!strcmp(typ->mangled, dst->mangled)) + { + void *this_ptr = (char *)cppobj - obj_locator->base_class_offset; + ret = get_this_pointer( &base_desc->offsets, this_ptr ); + break; + } + } + if (!ret && do_throw) + { + const char *msg = "Bad dynamic_cast!"; + bad_cast e; + MSVCRT_bad_cast_ctor( &e, &msg ); + _CxxThrowException( &e, &bad_cast_exception_type ); + } + } + __EXCEPT_PAGE_FAULT + { + __non_rtti_object e; + MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" ); + _CxxThrowException( &e, &__non_rtti_object_exception_type ); + return NULL; + } + __ENDTRY + return ret; +} +#endif + + +/****************************************************************** + * __RTCastToVoid (MSVCRT.@) + * + * Dynamically cast a C++ object to a void*. + * + * PARAMS + * cppobj [I] The C++ object to cast + * + * RETURNS + * Success: The base address of the object as a void*. + * Failure: NULL, if cppobj is NULL or has no RTTI. + * + * NOTES + * This function is usually called by compiler generated code as a result + * of using one of the C++ dynamic cast statements. + */ +void* CDECL MSVCRT___RTCastToVoid(void *cppobj) +{ + void *ret; + + if (!cppobj) return NULL; + + __TRY + { + const rtti_object_locator *obj_locator = get_obj_locator( cppobj ); + ret = (char *)cppobj - obj_locator->base_class_offset; + } + __EXCEPT_PAGE_FAULT + { + __non_rtti_object e; + MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" ); + _CxxThrowException( &e, &__non_rtti_object_exception_type ); + return NULL; + } + __ENDTRY + return ret; +} + + +/********************************************************************* + * _CxxThrowException (MSVCRT.@) + */ +#ifndef __x86_64__ +void WINAPI _CxxThrowException( exception *object, const cxx_exception_type *type ) +{ + ULONG_PTR args[3]; + + args[0] = CXX_FRAME_MAGIC_VC6; + args[1] = (ULONG_PTR)object; + args[2] = (ULONG_PTR)type; + RaiseException( CXX_EXCEPTION, EH_NONCONTINUABLE, 3, args ); +} +#else +void WINAPI _CxxThrowException( exception *object, const cxx_exception_type *type ) +{ + ULONG_PTR args[4]; + + args[0] = CXX_FRAME_MAGIC_VC6; + args[1] = (ULONG_PTR)object; + args[2] = (ULONG_PTR)type; + RtlPcToFileHeader( (void*)type, (void**)&args[3]); + RaiseException( CXX_EXCEPTION, EH_NONCONTINUABLE, 4, args ); +} +#endif + +#if _MSVCR_VER >= 80 + +/********************************************************************* + * ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z + * ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z + */ +#ifndef __x86_64__ +int __cdecl _is_exception_typeof(const type_info *ti, EXCEPTION_POINTERS *ep) +{ + int ret = -1; + + TRACE("(%p %p)\n", ti, ep); + + __TRY + { + EXCEPTION_RECORD *rec = ep->ExceptionRecord; + + if (rec->ExceptionCode==CXX_EXCEPTION && rec->NumberParameters==3 && + (rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC6 || + rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC7 || + rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC8)) + { + const cxx_type_info_table *tit = ((cxx_exception_type*)rec->ExceptionInformation[2])->type_info_table; + int i; + + for (i=0; i<tit->count; i++) { + if (ti==tit->info[i]->type_info || !strcmp(ti->mangled, tit->info[i]->type_info->mangled)) + { + ret = 1; + break; + } + } + + if (i == tit->count) + ret = 0; + } + } + __EXCEPT_PAGE_FAULT + __ENDTRY + + if(ret == -1) + MSVCRT_terminate(); + return ret; +} +#else +int __cdecl _is_exception_typeof(const type_info *ti, EXCEPTION_POINTERS *ep) +{ + int ret = -1; + + TRACE("(%p %p)\n", ti, ep); + + __TRY + { + EXCEPTION_RECORD *rec = ep->ExceptionRecord; + + if (rec->ExceptionCode==CXX_EXCEPTION && rec->NumberParameters==4 && + (rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC6 || + rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC7 || + rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC8)) + { + const cxx_exception_type *et = (cxx_exception_type*)rec->ExceptionInformation[2]; + const cxx_type_info_table *tit = (const cxx_type_info_table*)(rec->ExceptionInformation[3]+et->type_info_table); + int i; + + for (i=0; i<tit->count; i++) { + const cxx_type_info *cti = (const cxx_type_info*)(rec->ExceptionInformation[3]+tit->info[i]); + const type_info *except_ti = (const type_info*)(rec->ExceptionInformation[3]+cti->type_info); + if (ti==except_ti || !strcmp(ti->mangled, except_ti->mangled)) + { + ret = 1; + break; + } + } + + if (i == tit->count) + ret = 0; + } + } + __EXCEPT_PAGE_FAULT + __ENDTRY ... 5675 lines suppressed ...