From e7bd1b03da079a4990be37ebdfd536e740548413 Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Fri, 29 Mar 2019 16:04:59 +0100 Subject: [PATCH] msvcp140: Don't forward __ExceptionPtrDestroy to msvcr120. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46800 Signed-off-by: Piotr Caban Signed-off-by: Alexandre Julliard --- dlls/msvcp140/msvcp140.spec | 4 +-- dlls/msvcp90/exception.c | 51 +++++++++++++++++++++++++++++++++++++ dlls/msvcp90/msvcp90.h | 1 + 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/dlls/msvcp140/msvcp140.spec b/dlls/msvcp140/msvcp140.spec index 20f542e3dca..96dff341d35 100644 --- a/dlls/msvcp140/msvcp140.spec +++ b/dlls/msvcp140/msvcp140.spec @@ -1701,8 +1701,8 @@ @ cdecl -arch=win64 ?__ExceptionPtrCreate@@YAXPEAX@Z(ptr) __ExceptionPtrCreate @ cdecl -arch=win32 ?__ExceptionPtrCurrentException@@YAXPAX@Z(ptr) msvcr120.?__ExceptionPtrCurrentException@@YAXPAX@Z @ cdecl -arch=win64 ?__ExceptionPtrCurrentException@@YAXPEAX@Z(ptr) msvcr120.?__ExceptionPtrCurrentException@@YAXPEAX@Z -@ cdecl -arch=win32 ?__ExceptionPtrDestroy@@YAXPAX@Z(ptr) msvcr120.?__ExceptionPtrDestroy@@YAXPAX@Z -@ cdecl -arch=win64 ?__ExceptionPtrDestroy@@YAXPEAX@Z(ptr) msvcr120.?__ExceptionPtrDestroy@@YAXPEAX@Z +@ cdecl -arch=win32 ?__ExceptionPtrDestroy@@YAXPAX@Z(ptr) __ExceptionPtrDestroy +@ cdecl -arch=win64 ?__ExceptionPtrDestroy@@YAXPEAX@Z(ptr) __ExceptionPtrDestroy @ cdecl -arch=win32 ?__ExceptionPtrRethrow@@YAXPBX@Z(ptr) msvcr120.?__ExceptionPtrRethrow@@YAXPBX@Z @ cdecl -arch=win64 ?__ExceptionPtrRethrow@@YAXPEBX@Z(ptr) msvcr120.?__ExceptionPtrRethrow@@YAXPEBX@Z @ stub -arch=win32 ?__ExceptionPtrSwap@@YAXPAX0@Z diff --git a/dlls/msvcp90/exception.c b/dlls/msvcp90/exception.c index 5a382e3a074..142fddf66f9 100644 --- a/dlls/msvcp90/exception.c +++ b/dlls/msvcp90/exception.c @@ -23,7 +23,9 @@ #include "msvcp90.h" #include "windef.h" #include "winbase.h" +#include "winternl.h" #include "wine/debug.h" + WINE_DEFAULT_DEBUG_CHANNEL(msvcp); #define CLASS_IS_SIMPLE_TYPE 1 @@ -956,6 +958,10 @@ typedef struct int *ref; /* not binary compatible with native */ } exception_ptr; +/********************************************************************* + * ?__ExceptionPtrCreate@@YAXPAX@Z + * ?__ExceptionPtrCreate@@YAXPEAX@Z + */ void __cdecl __ExceptionPtrCreate(exception_ptr *ep) { TRACE("(%p)\n", ep); @@ -963,6 +969,51 @@ void __cdecl __ExceptionPtrCreate(exception_ptr *ep) ep->rec = NULL; ep->ref = NULL; } + +#ifdef __i386__ +extern void call_dtor(const cxx_exception_type *type, void *func, void *object); + +__ASM_GLOBAL_FUNC( call_dtor, + "movl 12(%esp),%ecx\n\t" + "call *8(%esp)\n\t" + "ret" ); +#elif __x86_64__ +static inline void call_dtor(const cxx_exception_type *type, unsigned int dtor, void *object) +{ + char *base = RtlPcToFileHeader((void*)type, (void**)&base); + void (__cdecl *func)(void*) = (void*)(base + dtor); + func(object); +} +#else +#define call_dtor(type, func, object) ((void (__cdecl*)(void*))(func))(object) +#endif + +/********************************************************************* + * ?__ExceptionPtrDestroy@@YAXPAX@Z + * ?__ExceptionPtrDestroy@@YAXPEAX@Z + */ +void __cdecl __ExceptionPtrDestroy(exception_ptr *ep) +{ + TRACE("(%p)\n", ep); + + if (!ep->rec) + return; + + if (!InterlockedDecrement(ep->ref)) + { + if (ep->rec->ExceptionCode == CXX_EXCEPTION) + { + const cxx_exception_type *type = (void*)ep->rec->ExceptionInformation[2]; + void *obj = (void*)ep->rec->ExceptionInformation[1]; + + if (type && type->destructor) call_dtor(type, type->destructor, obj); + HeapFree(GetProcessHeap(), 0, obj); + } + + HeapFree(GetProcessHeap(), 0, ep->rec); + HeapFree(GetProcessHeap(), 0, ep->ref); + } +} #endif #if _MSVCP_VER >= 70 || defined(_MSVCIRT) diff --git a/dlls/msvcp90/msvcp90.h b/dlls/msvcp90/msvcp90.h index 40fbe4ba80b..77c96e36f43 100644 --- a/dlls/msvcp90/msvcp90.h +++ b/dlls/msvcp90/msvcp90.h @@ -20,6 +20,7 @@ #include "windef.h" #include "cxx.h" +#define CXX_EXCEPTION 0xe06d7363 #define ALIGNED_SIZE(size, alignment) (((size)+((alignment)-1))/(alignment)*(alignment)) typedef unsigned char MSVCP_bool;