The tests for throwing/catching C++/CX exceptions is only enabled for targets with compiler support for exceptions.
From: Vibhav Pant vibhavp@gmail.com
--- dlls/vccorlib140/tests/vccorlib.c | 291 +++++++++++++++++++++++++++++- dlls/vccorlib140/vccorlib.c | 52 ++++++ dlls/vccorlib140/vccorlib140.spec | 102 +++++------ 3 files changed, 393 insertions(+), 52 deletions(-)
diff --git a/dlls/vccorlib140/tests/vccorlib.c b/dlls/vccorlib140/tests/vccorlib.c index 1b597a9325a..184e6c6d2cd 100644 --- a/dlls/vccorlib140/tests/vccorlib.c +++ b/dlls/vccorlib140/tests/vccorlib.c @@ -31,6 +31,7 @@ #include "windows.foundation.h" #include "winstring.h" #include "wine/test.h" +#include "wine/exception.h"
#define DEFINE_EXPECT(func) \ static BOOL expect_ ## func = FALSE; static unsigned int called_ ## func = 0 @@ -110,6 +111,22 @@ DEFINE_EXPECT(PostInitialize); DEFINE_EXPECT(PreUninitialize); DEFINE_EXPECT(PostUninitialize);
+#define WINRT_EXCEPTIONS \ + WINRT_EXCEPTION(AccessDenied, E_ACCESSDENIED) \ + WINRT_EXCEPTION(ChangedState, E_CHANGED_STATE) \ + WINRT_EXCEPTION(ClassNotRegistered, REGDB_E_CLASSNOTREG) \ + WINRT_EXCEPTION(Disconnected, RPC_E_DISCONNECTED) \ + WINRT_EXCEPTION(Failure, E_FAIL) \ + WINRT_EXCEPTION(InvalidArgument, E_INVALIDARG) \ + WINRT_EXCEPTION(InvalidCast, E_NOINTERFACE) \ + WINRT_EXCEPTION(NotImplemented, E_NOTIMPL) \ + WINRT_EXCEPTION(NullReference, E_POINTER) \ + WINRT_EXCEPTION(ObjectDisposed, RO_E_CLOSED) \ + WINRT_EXCEPTION(OperationCanceled, E_ABORT) \ + WINRT_EXCEPTION(OutOfBounds, E_BOUNDS) \ + WINRT_EXCEPTION(OutOfMemory, E_OUTOFMEMORY) \ + WINRT_EXCEPTION(WrongThread, RPC_E_WRONG_THREAD) + struct __abi_type_descriptor { const WCHAR *name; @@ -130,6 +147,10 @@ static int (__cdecl *p_platform_type_GetTypeCode)(void *); static HSTRING (__cdecl *p_platform_type_ToString)(void *); static HSTRING (__cdecl *p_platform_type_get_FullName)(void *); static void *(WINAPI *pCreateValue)(int type, const void *); +static void *(__cdecl *pCreateException)(HRESULT); +static void *(__cdecl *pCreateExceptionWithMessage)(HRESULT, HSTRING); +static HSTRING (__cdecl *p_platform_exception_get_Message)(void *); +static void (WINAPI *p___abi_WinRTraiseCOMException)(HRESULT);
static void *(__cdecl *p__RTtypeid)(const void *); static const char *(__thiscall *p_type_info_name)(void *); @@ -137,11 +158,17 @@ static const char *(__thiscall *p_type_info_raw_name)(void *); static int (__thiscall *p_type_info_opequals_equals)(void *, void *); static int (__thiscall *p_type_info_opnot_equals)(void *, void *);
+#define WINRT_EXCEPTION(name, hr) static void (WINAPI *p___abi_WinRTraise##name##Exception)(void); +WINRT_EXCEPTIONS +#undef WINRT_EXCEPTION + +static HMODULE hmod; + static BOOL init(void) { - HMODULE hmod = LoadLibraryA("vccorlib140.dll"); HMODULE msvcrt = LoadLibraryA("msvcrt.dll");
+ hmod = LoadLibraryA("vccorlib140.dll"); if (!hmod) { win_skip("vccorlib140.dll not available\n"); @@ -173,6 +200,15 @@ static BOOL init(void) p_platform_type_ToString = (void *)GetProcAddress(hmod, "?ToString@Type@Platform@@U$AAAP$AAVString@2@XZ"); p_platform_type_get_FullName = (void *)GetProcAddress(hmod, "?get@FullName@Type@Platform@@Q$AAAP$AAVString@3@XZ"); pCreateValue = (void *)GetProcAddress(hmod, "?CreateValue@Details@Platform@@YAP$AAVObject@2@W4TypeCode@2@PBX@Z"); + pCreateException = (void *)GetProcAddress(hmod, "?CreateException@Exception@Platform@@SAP$AAV12@H@Z"); + pCreateExceptionWithMessage = (void *)GetProcAddress(hmod, + "?CreateException@Exception@Platform@@SAP$AAV12@HP$AAVString@2@@Z"); + p_platform_exception_get_Message = (void *)GetProcAddress(hmod, + "?get@Message@Exception@Platform@@Q$AAAP$AAVString@3@XZ"); + p___abi_WinRTraiseCOMException = (void *)GetProcAddress(hmod, "?__abi_WinRTraiseCOMException@@YAXJ@Z"); +#define WINRT_EXCEPTION(name, hr) p___abi_WinRTraise##name##Exception = (void *)GetProcAddress(hmod, "?__abi_WinRTraise" #name "Exception@@YAXXZ"); + WINRT_EXCEPTIONS +#undef WINRT_EXCEPTION p_type_info_name = (void *)GetProcAddress(msvcrt, "?name@type_info@@QBAPBDXZ"); p_type_info_raw_name = (void *)GetProcAddress(msvcrt, "?raw_name@type_info@@QBAPBDXZ"); p_type_info_opequals_equals = (void *)GetProcAddress(msvcrt, "??8type_info@@QBAHABV0@@Z"); @@ -198,6 +234,16 @@ static BOOL init(void) "?get@FullName@Type@Platform@@QE$AAAPE$AAVString@3@XZ"); pCreateValue = (void *)GetProcAddress(hmod, "?CreateValue@Details@Platform@@YAPE$AAVObject@2@W4TypeCode@2@PEBX@Z"); + pCreateException = (void *)GetProcAddress(hmod, + "?CreateException@Exception@Platform@@SAPE$AAV12@H@Z"); + pCreateExceptionWithMessage = (void *)GetProcAddress(hmod, + "?CreateException@Exception@Platform@@SAPE$AAV12@HPE$AAVString@2@@Z"); + p_platform_exception_get_Message = (void *)GetProcAddress(hmod, + "?get@Message@Exception@Platform@@QE$AAAPE$AAVString@3@XZ"); + p___abi_WinRTraiseCOMException = (void *)GetProcAddress(hmod, "?__abi_WinRTraiseCOMException@@YAXJ@Z"); +#define WINRT_EXCEPTION(name, hr) p___abi_WinRTraise##name##Exception = (void *)GetProcAddress(hmod, "?__abi_WinRTraise" #name "Exception@@YAXXZ"); + WINRT_EXCEPTIONS +#undef WINRT_EXCEPTION p_type_info_name = (void *)GetProcAddress(msvcrt, "?name@type_info@@QEBAPEBDXZ"); p_type_info_raw_name = (void *)GetProcAddress(msvcrt, "?raw_name@type_info@@QEBAPEBDXZ"); p_type_info_opequals_equals = (void *)GetProcAddress(msvcrt, "??8type_info@@QEBAHAEBV0@@Z"); @@ -222,6 +268,16 @@ static BOOL init(void) "?get@FullName@Type@Platform@@Q$AAAP$AAVString@3@XZ"); pCreateValue = (void *)GetProcAddress(hmod, "?CreateValue@Details@Platform@@YGP$AAVObject@2@W4TypeCode@2@PBX@Z"); + pCreateException = (void *)GetProcAddress(hmod, + "?CreateException@Exception@Platform@@SAP$AAV12@H@Z"); + pCreateExceptionWithMessage = (void *)GetProcAddress(hmod, + "?CreateException@Exception@Platform@@SAP$AAV12@HP$AAVString@2@@Z"); + p_platform_exception_get_Message = (void *)GetProcAddress(hmod, + "?get@Message@Exception@Platform@@Q$AAAP$AAVString@3@XZ"); + p___abi_WinRTraiseCOMException = (void *)GetProcAddress(hmod, "?__abi_WinRTraiseCOMException@@YGXJ@Z"); +#define WINRT_EXCEPTION(name, hr) p___abi_WinRTraise##name##Exception = (void *)GetProcAddress(hmod, "?__abi_WinRTraise" #name "Exception@@YGXXZ"); + WINRT_EXCEPTIONS +#undef WINRT_EXCEPTION p_type_info_name = (void *)GetProcAddress(msvcrt, "?name@type_info@@QBEPBDXZ"); p_type_info_raw_name = (void *)GetProcAddress(msvcrt, "?raw_name@type_info@@QBEPBDXZ"); p_type_info_opequals_equals = (void *)GetProcAddress(msvcrt, "??8type_info@@QBEHABV0@@Z"); @@ -240,6 +296,13 @@ static BOOL init(void) ok(p_platform_type_ToString != NULL, "Platform::Type::ToString not available\n"); ok(p_platform_type_get_FullName != NULL, "Platform::Type::FullName not available\n"); ok(pCreateValue != NULL, "CreateValue not available\n"); + ok(pCreateException != NULL, "CreateException not available\n"); + ok(pCreateExceptionWithMessage != NULL, "CreateExceptionWithMessage not available\n"); + ok(p_platform_exception_get_Message != NULL, "Platform::Exception::Message::get not available\n"); + ok(p___abi_WinRTraiseCOMException != NULL, "__abi_WinRTraiseCOMException not available\n"); +#define WINRT_EXCEPTION(name, hr) ok(p___abi_WinRTraise##name##Exception != NULL, "__abi__WinRTraise" #name "Exception not available\n"); + WINRT_EXCEPTIONS +#undef WINRT_EXCEPTION
ok(p_type_info_name != NULL, "type_info::name not available\n"); ok(p_type_info_raw_name != NULL, "type_info::raw_name not available\n"); @@ -1020,6 +1083,231 @@ static void test_CreateValue(void) pUninitializeData(0); }
+struct exception_test_case +{ + HRESULT hr; + void (WINAPI *func)(void); + const WCHAR *exp_winrt_name; + const char *exp_rtti_mangled_name; + const char *exp_rtti_name; + /* The mangled RTTI name of the type received by the exception handler/filter. */ + const char *exp_caugh_rtti_mangled_name; +}; +static const struct exception_test_case *cur_exception; + +typedef struct __type_info +{ + const void *vtable; + char *name; + char mangled[128]; +} type_info; +typedef struct +{ + UINT flags; + unsigned int type_info; + DWORD offsets[3]; + unsigned int size; + unsigned int copy_ctor; +} cxx_type_info; +typedef struct +{ + UINT count; + unsigned int info[1]; +} cxx_type_info_table; +typedef struct +{ + UINT flags; + unsigned int destructor; + unsigned int custom_handler; + unsigned int type_info_table; +} cxx_exception_type; + +#ifdef USE_COMPILER_EXCEPTIONS +static CALLBACK LONG cxx_exception_filter(EXCEPTION_POINTERS *ptrs) +{ + ULONG_PTR *info = ptrs->ExceptionRecord->ExceptionInformation; + const cxx_type_info_table *type_info_table; + const cxx_exception_type *type; + const cxx_type_info *cxx_info; + const type_info *rtti_info; + IInspectable *obj; + const WCHAR *bufW; + HSTRING name; + HRESULT hr; + UINT i; + + ok(ptrs->ExceptionRecord->NumberParameters == 4, "got NumberParameters %lu\n", + ptrs->ExceptionRecord->NumberParameters); + if (ptrs->ExceptionRecord->NumberParameters != 4) return 0; + + ok(info[0] == EXCEPTION_WINE_CXX_FRAME_MAGIC, "got info[0] %#Ix\n", info[0]); + + type = (cxx_exception_type *)info[2]; + ok(type->flags == 0x10, "got flags %#x\n", type->flags); + ok(type->destructor == 0, "got destructor %#x\n", type->destructor); + ok(type->custom_handler == 0, "got custom_handler %#x\n", type->custom_handler); + ok(type->type_info_table != 0, "got type_info_table %#x\n", type->type_info_table); + + ok(info[3] == (ULONG_PTR)hmod, "got info[3] %#Ix != %p\n", info[3], hmod); + if (info[3] != (ULONG_PTR)hmod) return 0; + + type_info_table = (cxx_type_info_table *)((ULONG_PTR)hmod + type->type_info_table); + ok(type_info_table->count != 0, "got type_info_table->count %u\n", type_info_table->count); + + for (i = 0; i < type_info_table->count; i++) + { + cxx_info = (cxx_type_info *)((ULONG_PTR)hmod + type_info_table->info[i]); + /* There is no copy constructor, presumably because they already have COM semantics.*/ + ok(cxx_info->copy_ctor == 0, "got copy_ctor %#x\n", cxx_info->copy_ctor); + ok(cxx_info->type_info != 0, "got type_info"); + } + + cxx_info = (cxx_type_info *)((ULONG_PTR)hmod + type_info_table->info[0]); + rtti_info = (type_info *)((ULONG_PTR)hmod + cxx_info->type_info); + ok(!strcmp(rtti_info->mangled, cur_exception->exp_caugh_rtti_mangled_name), "got mangled %s != %s\n", + debugstr_a(rtti_info->mangled), debugstr_a(cur_exception->exp_caugh_rtti_mangled_name)); + + obj = *((IInspectable **)info[1]); + hr = IInspectable_GetRuntimeClassName(obj, &name); + ok(hr == S_OK, "got hr %#lx\n", hr); + bufW = WindowsGetStringRawBuffer(name, NULL); + ok(!wcscmp(bufW, cur_exception->exp_winrt_name), "got name %s\n", debugstr_hstring(name)); + WindowsDeleteString(name); + + return 1; +} +#endif + +static void test_exceptions(void) +{ +#define WINRT_EXCEPTION(name, hr) \ + {hr, p___abi_WinRTraise##name##Exception, L"Platform." #name "Exception", ".?AV" #name "Exception@Platform@@", \ + "class Platform::" #name "Exception", ".PE$AAV" #name "Exception@Platform@@"}, + + const struct exception_test_case test_cases[] = { + WINRT_EXCEPTIONS + /* Generic exceptions */ + {E_HANDLE, NULL, L"Platform.COMException", ".?AVCOMException@Platform@@", "class Platform::COMException", ".PE$AAVCOMException@Platform@@"}, + {0xdeadbeef, NULL, L"Platform.COMException", ".?AVCOMException@Platform@@", "class Platform::COMException", ".PE$AAVCOMException@Platform@@"}, + }; +#undef WINRT_EXCEPTION + HSTRING_HEADER hdr; + HSTRING msg; + HRESULT hr; + ULONG i; + + hr = WindowsCreateStringReference(L"foo", 3, &hdr, &msg); + ok(hr == S_OK, "got hr %#lx\n", hr); + + for (i = 0; i < ARRAY_SIZE(test_cases); i++) + { +#ifdef USE_COMPILER_EXCEPTIONS + BOOL caught = FALSE; +#endif + const char *rtti_name, *rtti_raw_name; + IInspectable *excp; + const WCHAR *bufW; + void *type_info; + WCHAR buf[256]; + INT32 ret = 0; + HSTRING str; + ULONG count; + HRESULT hr; + GUID *iids; + + winetest_push_context("test_cases[%lu]", i); + + cur_exception = &test_cases[i]; + excp = pCreateException(cur_exception->hr); + todo_wine ok(excp != NULL, "got excp %p\n", excp); + if (!excp) + { + winetest_pop_context(); + continue; + } + check_interface(excp, &IID_IUnknown); + check_interface(excp, &IID_IInspectable); + check_interface(excp, &IID_IAgileObject); + check_interface(excp, &IID_IMarshal); + check_interface(excp, &IID_IClosable); + + hr = IInspectable_GetRuntimeClassName(excp, &str); + ok(hr == S_OK, "got hr %#lx\n", hr); + bufW = WindowsGetStringRawBuffer(str, NULL); + ok(!wcscmp(cur_exception->exp_winrt_name, bufW), "got str %s != %s\n", debugstr_hstring(str), + debugstr_w(cur_exception->exp_winrt_name)); + WindowsDeleteString(str); + + count = 1; + /* GetIids does not return any IIDs for Platform::Exception objects. */ + hr = IInspectable_GetIids(excp, &count, &iids); + ok(hr == S_OK, "got hr %#lx\n", hr); + ok(count == 0, "got count %lu\n", count); + CoTaskMemFree(iids); + + type_info = p__RTtypeid(excp); + ok(type_info != NULL, "got type_info %p\n", type_info); + rtti_name = (char *)call_func1(p_type_info_name, type_info); + ok(rtti_name && !strcmp(rtti_name, cur_exception->exp_rtti_name), "got rtti_name %s != %s\n", + debugstr_a(rtti_name), debugstr_a(cur_exception->exp_rtti_name)); + rtti_raw_name = (char *)call_func1(p_type_info_raw_name, type_info); + ok(rtti_raw_name && !strcmp(rtti_raw_name, cur_exception->exp_rtti_mangled_name), "got rtti_raw_name %s != %s\n", + debugstr_a(rtti_raw_name), debugstr_a(cur_exception->exp_rtti_mangled_name)); + + /* By default, the message returned is from FormatMessageW. */ + str = p_platform_exception_get_Message(excp); + ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, cur_exception->hr, 0, buf, ARRAY_SIZE(buf), NULL); + ok(!!str == !!ret, "got str %s\n", debugstr_hstring(str)); + if(ret) + { + bufW = WindowsGetStringRawBuffer(str, NULL); + ok(!wcscmp(bufW, buf), "got str %s != %s\n", debugstr_hstring(str), debugstr_w(buf)); + } + WindowsDeleteString(str); + count = IInspectable_Release(excp); + ok(count == 0, "got count %lu\n", count); + + /* Create an Exception object with a custom message. */ + excp = pCreateExceptionWithMessage(cur_exception->hr, msg); + ok(excp != NULL, "got excp %p\n", excp); + str = p_platform_exception_get_Message(excp); + hr = WindowsCompareStringOrdinal(str, msg, &ret); + ok(hr == S_OK, "got hr %#lx\n", hr); + ok(!ret, "got str %s != %s\n", debugstr_hstring(str), debugstr_hstring(msg)); + WindowsDeleteString(str); + count = IInspectable_Release(excp); + ok(count == 0, "got count %lu\n", count); + +#ifdef USE_COMPILER_EXCEPTIONS + if (cur_exception->func) + { + __TRY + { + cur_exception->func(); + } + __EXCEPT(cxx_exception_filter) + { + caught = TRUE; + } + __ENDTRY; + ok(caught, "got caught %d\n", caught); + } + caught = FALSE; + __TRY + { + p___abi_WinRTraiseCOMException(cur_exception->hr); + } + __EXCEPT(cxx_exception_filter) + { + caught = TRUE; + } + __ENDTRY; + ok(caught, "got caught %d\n", caught); +#endif + winetest_pop_context(); + } +} + START_TEST(vccorlib) { if(!init()) @@ -1033,4 +1321,5 @@ START_TEST(vccorlib) test_AllocateWithWeakRef(); test___abi_make_type_id(); test_CreateValue(); + test_exceptions(); } diff --git a/dlls/vccorlib140/vccorlib.c b/dlls/vccorlib140/vccorlib.c index 3294aab6dd0..121c4bc43b2 100644 --- a/dlls/vccorlib140/vccorlib.c +++ b/dlls/vccorlib140/vccorlib.c @@ -25,6 +25,7 @@ #include "roapi.h" #include "weakreference.h" #include "winstring.h" +#include "errhandlingapi.h" #define WIDL_using_Windows_Foundation #include "windows.foundation.h" #include "wine/asm.h" @@ -557,6 +558,57 @@ void *WINAPI CreateValue(int typecode, const void *val) return obj; }
+void WINAPI __abi_WinRTraiseCOMException(HRESULT hr) +{ + FIXME("(%#lx): stub!\n", hr); + RaiseFailFastException(NULL, NULL, 0); +} + +#define WINRT_EXCEPTIONS \ + WINRT_EXCEPTION(AccessDenied, E_ACCESSDENIED) \ + WINRT_EXCEPTION(ChangedState, E_CHANGED_STATE) \ + WINRT_EXCEPTION(ClassNotRegistered, REGDB_E_CLASSNOTREG) \ + WINRT_EXCEPTION(Disconnected, RPC_E_DISCONNECTED) \ + WINRT_EXCEPTION(Failure, E_FAIL) \ + WINRT_EXCEPTION(InvalidArgument, E_INVALIDARG) \ + WINRT_EXCEPTION(InvalidCast, E_NOINTERFACE) \ + WINRT_EXCEPTION(NotImplemented, E_NOTIMPL) \ + WINRT_EXCEPTION(NullReference, E_POINTER) \ + WINRT_EXCEPTION(ObjectDisposed, RO_E_CLOSED) \ + WINRT_EXCEPTION(OperationCanceled, E_ABORT) \ + WINRT_EXCEPTION(OutOfBounds, E_BOUNDS) \ + WINRT_EXCEPTION(OutOfMemory, E_OUTOFMEMORY) \ + WINRT_EXCEPTION(WrongThread, RPC_E_WRONG_THREAD) + +#define WINRT_EXCEPTION(name, hr) \ + void WINAPI __abi_WinRTraise##name##Exception(void) \ + { \ + TRACE("()\n"); \ + __abi_WinRTraiseCOMException((hr)); \ + } + +WINRT_EXCEPTIONS + +#undef WINRT_EXCEPTION + +void *__cdecl CreateExceptionWithMessage(HRESULT hr, HSTRING msg) +{ + FIXME("(%#lx, %s): stub!\n", hr, debugstr_hstring(msg)); + return NULL; +} + +void *__cdecl CreateException(HRESULT hr) +{ + FIXME("(%#lx): stub!\n", hr); + return NULL; +} + +HSTRING __cdecl platform_exception_get_Message(void *excp) +{ + FIXME("(%p): stub!\n", excp); + return NULL; +} + BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) { if (reason == DLL_PROCESS_ATTACH) diff --git a/dlls/vccorlib140/vccorlib140.spec b/dlls/vccorlib140/vccorlib140.spec index d146b07d30e..5c15e8c88bc 100644 --- a/dlls/vccorlib140/vccorlib140.spec +++ b/dlls/vccorlib140/vccorlib140.spec @@ -295,53 +295,53 @@ @ stub -arch=win64 ?__abi_ObjectToString@__abi_details@@YAPE$AAVString@Platform@@PE$AAVObject@3@_N@Z @ stub -arch=win32 ?__abi_Resolve@ControlBlock@Details@Platform@@UAGJAAVGuid@3@PAPAU__abi_IInspectable@@@Z @ stub -arch=win64 ?__abi_Resolve@ControlBlock@Details@Platform@@UEAAJAEAVGuid@3@PEAPEAU__abi_IInspectable@@@Z -@ stub -arch=i386 ?__abi_WinRTraiseAccessDeniedException@@YGXXZ -@ stub -arch=arm ?__abi_WinRTraiseAccessDeniedException@@YAXXZ -@ stub -arch=win64 ?__abi_WinRTraiseAccessDeniedException@@YAXXZ -@ stub -arch=i386 ?__abi_WinRTraiseCOMException@@YGXJ@Z -@ stub -arch=arm ?__abi_WinRTraiseCOMException@@YAXJ@Z -@ stub -arch=win64 ?__abi_WinRTraiseCOMException@@YAXJ@Z -@ stub -arch=i386 ?__abi_WinRTraiseChangedStateException@@YGXXZ -@ stub -arch=arm ?__abi_WinRTraiseChangedStateException@@YAXXZ -@ stub -arch=win64 ?__abi_WinRTraiseChangedStateException@@YAXXZ -@ stub -arch=i386 ?__abi_WinRTraiseClassNotRegisteredException@@YGXXZ -@ stub -arch=arm ?__abi_WinRTraiseClassNotRegisteredException@@YAXXZ -@ stub -arch=win64 ?__abi_WinRTraiseClassNotRegisteredException@@YAXXZ -@ stub -arch=i386 ?__abi_WinRTraiseDisconnectedException@@YGXXZ -@ stub -arch=arm ?__abi_WinRTraiseDisconnectedException@@YAXXZ -@ stub -arch=win64 ?__abi_WinRTraiseDisconnectedException@@YAXXZ -@ stub -arch=i386 ?__abi_WinRTraiseFailureException@@YGXXZ -@ stub -arch=arm ?__abi_WinRTraiseFailureException@@YAXXZ -@ stub -arch=win64 ?__abi_WinRTraiseFailureException@@YAXXZ -@ stub -arch=i386 ?__abi_WinRTraiseInvalidArgumentException@@YGXXZ -@ stub -arch=arm ?__abi_WinRTraiseInvalidArgumentException@@YAXXZ -@ stub -arch=win64 ?__abi_WinRTraiseInvalidArgumentException@@YAXXZ -@ stub -arch=i386 ?__abi_WinRTraiseInvalidCastException@@YGXXZ -@ stub -arch=arm ?__abi_WinRTraiseInvalidCastException@@YAXXZ -@ stub -arch=win64 ?__abi_WinRTraiseInvalidCastException@@YAXXZ +@ stdcall -arch=i386 ?__abi_WinRTraiseAccessDeniedException@@YGXXZ() __abi_WinRTraiseAccessDeniedException +@ stdcall -arch=arm ?__abi_WinRTraiseAccessDeniedException@@YAXXZ() __abi_WinRTraiseAccessDeniedException +@ stdcall -arch=win64 ?__abi_WinRTraiseAccessDeniedException@@YAXXZ() __abi_WinRTraiseAccessDeniedException +@ stdcall -arch=i386 ?__abi_WinRTraiseCOMException@@YGXJ@Z(long) __abi_WinRTraiseCOMException +@ stdcall -arch=arm ?__abi_WinRTraiseCOMException@@YAXJ@Z(long) __abi_WinRTraiseCOMException +@ stdcall -arch=win64 ?__abi_WinRTraiseCOMException@@YAXJ@Z(long) __abi_WinRTraiseCOMException +@ stdcall -arch=i386 ?__abi_WinRTraiseChangedStateException@@YGXXZ() __abi_WinRTraiseChangedStateException +@ stdcall -arch=arm ?__abi_WinRTraiseChangedStateException@@YAXXZ() __abi_WinRTraiseChangedStateException +@ stdcall -arch=win64 ?__abi_WinRTraiseChangedStateException@@YAXXZ() __abi_WinRTraiseChangedStateException +@ stdcall -arch=i386 ?__abi_WinRTraiseClassNotRegisteredException@@YGXXZ() __abi_WinRTraiseClassNotRegisteredException +@ stdcall -arch=arm ?__abi_WinRTraiseClassNotRegisteredException@@YAXXZ() __abi_WinRTraiseClassNotRegisteredException +@ stdcall -arch=win64 ?__abi_WinRTraiseClassNotRegisteredException@@YAXXZ() __abi_WinRTraiseClassNotRegisteredException +@ stdcall -arch=i386 ?__abi_WinRTraiseDisconnectedException@@YGXXZ() __abi_WinRTraiseDisconnectedException +@ stdcall -arch=arm ?__abi_WinRTraiseDisconnectedException@@YAXXZ() __abi_WinRTraiseDisconnectedException +@ stdcall -arch=win64 ?__abi_WinRTraiseDisconnectedException@@YAXXZ() __abi_WinRTraiseDisconnectedException +@ stdcall -arch=i386 ?__abi_WinRTraiseFailureException@@YGXXZ() __abi_WinRTraiseFailureException +@ stdcall -arch=arm ?__abi_WinRTraiseFailureException@@YAXXZ() __abi_WinRTraiseFailureException +@ stdcall -arch=win64 ?__abi_WinRTraiseFailureException@@YAXXZ() __abi_WinRTraiseFailureException +@ stdcall -arch=i386 ?__abi_WinRTraiseInvalidArgumentException@@YGXXZ() __abi_WinRTraiseInvalidArgumentException +@ stdcall -arch=arm ?__abi_WinRTraiseInvalidArgumentException@@YAXXZ() __abi_WinRTraiseInvalidArgumentException +@ stdcall -arch=win64 ?__abi_WinRTraiseInvalidArgumentException@@YAXXZ() __abi_WinRTraiseInvalidArgumentException +@ stdcall -arch=i386 ?__abi_WinRTraiseInvalidCastException@@YGXXZ() __abi_WinRTraiseInvalidCastException +@ stdcall -arch=arm ?__abi_WinRTraiseInvalidCastException@@YAXXZ() __abi_WinRTraiseInvalidCastException +@ stdcall -arch=win64 ?__abi_WinRTraiseInvalidCastException@@YAXXZ() __abi_WinRTraiseInvalidCastException @ stub -arch=win32 ??0IntPtr@Platform@@QAA@H@Z @ stub -arch=win64 ??0IntPtr@Platform@@QEAA@H@Z -@ stub -arch=i386 ?__abi_WinRTraiseNotImplementedException@@YGXXZ -@ stub -arch=arm ?__abi_WinRTraiseNotImplementedException@@YAXXZ -@ stub -arch=win64 ?__abi_WinRTraiseNotImplementedException@@YAXXZ -@ stub -arch=i386 ?__abi_WinRTraiseNullReferenceException@@YGXXZ -@ stub -arch=arm ?__abi_WinRTraiseNullReferenceException@@YAXXZ -@ stub -arch=win64 ?__abi_WinRTraiseNullReferenceException@@YAXXZ -@ stub -arch=i386 ?__abi_WinRTraiseObjectDisposedException@@YGXXZ -@ stub -arch=arm ?__abi_WinRTraiseObjectDisposedException@@YAXXZ -@ stub -arch=win64 ?__abi_WinRTraiseObjectDisposedException@@YAXXZ -@ stub -arch=i386 ?__abi_WinRTraiseOperationCanceledException@@YGXXZ -@ stub -arch=arm ?__abi_WinRTraiseOperationCanceledException@@YAXXZ -@ stub -arch=win64 ?__abi_WinRTraiseOperationCanceledException@@YAXXZ -@ stub -arch=i386 ?__abi_WinRTraiseOutOfBoundsException@@YGXXZ -@ stub -arch=arm ?__abi_WinRTraiseOutOfBoundsException@@YAXXZ -@ stub -arch=win64 ?__abi_WinRTraiseOutOfBoundsException@@YAXXZ -@ stub -arch=i386 ?__abi_WinRTraiseOutOfMemoryException@@YGXXZ -@ stub -arch=arm ?__abi_WinRTraiseOutOfMemoryException@@YAXXZ -@ stub -arch=win64 ?__abi_WinRTraiseOutOfMemoryException@@YAXXZ -@ stub -arch=i386 ?__abi_WinRTraiseWrongThreadException@@YGXXZ -@ stub -arch=arm ?__abi_WinRTraiseWrongThreadException@@YAXXZ -@ stub -arch=win64 ?__abi_WinRTraiseWrongThreadException@@YAXXZ +@ stdcall -arch=i386 ?__abi_WinRTraiseNotImplementedException@@YGXXZ() __abi_WinRTraiseNotImplementedException +@ stdcall -arch=arm ?__abi_WinRTraiseNotImplementedException@@YAXXZ() __abi_WinRTraiseNotImplementedException +@ stdcall -arch=win64 ?__abi_WinRTraiseNotImplementedException@@YAXXZ() __abi_WinRTraiseNotImplementedException +@ stdcall -arch=i386 ?__abi_WinRTraiseNullReferenceException@@YGXXZ() __abi_WinRTraiseNullReferenceException +@ stdcall -arch=arm ?__abi_WinRTraiseNullReferenceException@@YAXXZ() __abi_WinRTraiseNullReferenceException +@ stdcall -arch=win64 ?__abi_WinRTraiseNullReferenceException@@YAXXZ() __abi_WinRTraiseNullReferenceException +@ stdcall -arch=i386 ?__abi_WinRTraiseObjectDisposedException@@YGXXZ() __abi_WinRTraiseObjectDisposedException +@ stdcall -arch=arm ?__abi_WinRTraiseObjectDisposedException@@YAXXZ() __abi_WinRTraiseObjectDisposedException +@ stdcall -arch=win64 ?__abi_WinRTraiseObjectDisposedException@@YAXXZ() __abi_WinRTraiseObjectDisposedException +@ stdcall -arch=i386 ?__abi_WinRTraiseOperationCanceledException@@YGXXZ() __abi_WinRTraiseOperationCanceledException +@ stdcall -arch=arm ?__abi_WinRTraiseOperationCanceledException@@YAXXZ() __abi_WinRTraiseOperationCanceledException +@ stdcall -arch=win64 ?__abi_WinRTraiseOperationCanceledException@@YAXXZ() __abi_WinRTraiseOperationCanceledException +@ stdcall -arch=i386 ?__abi_WinRTraiseOutOfBoundsException@@YGXXZ() __abi_WinRTraiseOutOfBoundsException +@ stdcall -arch=arm ?__abi_WinRTraiseOutOfBoundsException@@YAXXZ() __abi_WinRTraiseOutOfBoundsException +@ stdcall -arch=win64 ?__abi_WinRTraiseOutOfBoundsException@@YAXXZ() __abi_WinRTraiseOutOfBoundsException +@ stdcall -arch=i386 ?__abi_WinRTraiseOutOfMemoryException@@YGXXZ() __abi_WinRTraiseOutOfMemoryException +@ stdcall -arch=arm ?__abi_WinRTraiseOutOfMemoryException@@YAXXZ() __abi_WinRTraiseOutOfMemoryException +@ stdcall -arch=win64 ?__abi_WinRTraiseOutOfMemoryException@@YAXXZ() __abi_WinRTraiseOutOfMemoryException +@ stdcall -arch=i386 ?__abi_WinRTraiseWrongThreadException@@YGXXZ() __abi_WinRTraiseWrongThreadException +@ stdcall -arch=arm ?__abi_WinRTraiseWrongThreadException@@YAXXZ() __abi_WinRTraiseWrongThreadException +@ stdcall -arch=win64 ?__abi_WinRTraiseWrongThreadException@@YAXXZ() __abi_WinRTraiseWrongThreadException @ stub -arch=i386 ?__abi_cast_Object_to_String@__abi_details@@YGP$AAVString@Platform@@_NP$AAVObject@3@@Z @ stub -arch=arm ?__abi_cast_Object_to_String@__abi_details@@YAP$AAVString@Platform@@_NP$AAVObject@3@@Z @ stub -arch=win64 ?__abi_cast_Object_to_String@__abi_details@@YAPE$AAVString@Platform@@_NPE$AAVObject@3@@Z @@ -372,8 +372,8 @@ @ stub -arch=win64 ?get@HasInverse@Matrix3D@Media3D@Media@Xaml@UI@Windows@@QEAA_NXZ @ stub -arch=win32 ??0InvalidArgumentException@Platform@@Q$AAA@P$AAVString@1@@Z @ stub -arch=win64 ??0InvalidArgumentException@Platform@@QE$AAA@PE$AAVString@1@@Z -@ stub -arch=win32 ?get@Message@Exception@Platform@@Q$AAAP$AAVString@3@XZ -@ stub -arch=win64 ?get@Message@Exception@Platform@@QE$AAAPE$AAVString@3@XZ +@ cdecl -arch=win32 ?get@Message@Exception@Platform@@Q$AAAP$AAVString@3@XZ(ptr) platform_exception_get_Message +@ cdecl -arch=win64 ?get@Message@Exception@Platform@@QE$AAAPE$AAVString@3@XZ(ptr) platform_exception_get_Message @ stub ?get@ObjectCount@Heap@Details@Platform@@SAHXZ @ stub -arch=win32 ?get@Right@Rect@Foundation@Windows@@QAAMXZ @ stub -arch=win64 ?get@Right@Rect@Foundation@Windows@@QEAAMXZ @@ -516,10 +516,10 @@ @ stub -arch=win64 ??0COMException@Platform@@QE$AAA@HPE$AAVString@1@@Z @ stub -arch=win32 ?Contains@Rect@Foundation@Windows@@QAA_NVPoint@23@@Z @ stub -arch=win64 ?Contains@Rect@Foundation@Windows@@QEAA_NVPoint@23@@Z -@ stub -arch=win32 ?CreateException@Exception@Platform@@SAP$AAV12@H@Z -@ stub -arch=win64 ?CreateException@Exception@Platform@@SAPE$AAV12@H@Z -@ stub -arch=win32 ?CreateException@Exception@Platform@@SAP$AAV12@HP$AAVString@2@@Z -@ stub -arch=win64 ?CreateException@Exception@Platform@@SAPE$AAV12@HPE$AAVString@2@@Z +@ cdecl -arch=win32 ?CreateException@Exception@Platform@@SAP$AAV12@H@Z(long) CreateException +@ cdecl -arch=win64 ?CreateException@Exception@Platform@@SAPE$AAV12@H@Z(long) CreateException +@ cdecl -arch=win32 ?CreateException@Exception@Platform@@SAP$AAV12@HP$AAVString@2@@Z(long ptr) CreateExceptionWithMessage +@ cdecl -arch=win64 ?CreateException@Exception@Platform@@SAPE$AAV12@HPE$AAVString@2@@Z(long ptr) CreateExceptionWithMessage @ stdcall -arch=i386 ?CreateValue@Details@Platform@@YGP$AAVObject@2@W4TypeCode@2@PBX@Z(long ptr) CreateValue @ stdcall -arch=arm ?CreateValue@Details@Platform@@YAP$AAVObject@2@W4TypeCode@2@PBX@Z(long ptr) CreateValue @ stdcall -arch=win64 ?CreateValue@Details@Platform@@YAPE$AAVObject@2@W4TypeCode@2@PEBX@Z(long ptr) CreateValue
Piotr Caban (@piotr) commented about dlls/vccorlib140/vccorlib140.spec:
@ stub -arch=win64 ?__abi_ObjectToString@__abi_details@@YAPE$AAVString@Platform@@PE$AAVObject@3@_N@Z @ stub -arch=win32 ?__abi_Resolve@ControlBlock@Details@Platform@@UAGJAAVGuid@3@PAPAU__abi_IInspectable@@@Z @ stub -arch=win64 ?__abi_Resolve@ControlBlock@Details@Platform@@UEAAJAEAVGuid@3@PEAPEAU__abi_IInspectable@@@Z -@ stub -arch=i386 ?__abi_WinRTraiseAccessDeniedException@@YGXXZ -@ stub -arch=arm ?__abi_WinRTraiseAccessDeniedException@@YAXXZ -@ stub -arch=win64 ?__abi_WinRTraiseAccessDeniedException@@YAXXZ
arm and win64 exports are identical and can be merged.
Piotr Caban (@piotr) commented about dlls/vccorlib140/tests/vccorlib.c:
+} cxx_type_info; +typedef struct +{
- UINT count;
- unsigned int info[1];
+} cxx_type_info_table; +typedef struct +{
- UINT flags;
- unsigned int destructor;
- unsigned int custom_handler;
- unsigned int type_info_table;
+} cxx_exception_type;
+#ifdef USE_COMPILER_EXCEPTIONS +static CALLBACK LONG cxx_exception_filter(EXCEPTION_POINTERS *ptrs)
This code depends on a lot of exception handling related details. Because of that it will not work in i386 case (in theory one can compile i386 tests with MSVC, it will also need to be updated when i386 Clang compiler exception support is enabled). It also leaks exception objects. I think it would be best to avoid most of these tests.
If it's really needed to test that I would suggest to limit it to only getting the exception object and doing some tests on it.
Piotr Caban (@piotr) commented about dlls/vccorlib140/vccorlib.c:
- WINRT_EXCEPTION(InvalidArgument, E_INVALIDARG) \
- WINRT_EXCEPTION(InvalidCast, E_NOINTERFACE) \
- WINRT_EXCEPTION(NotImplemented, E_NOTIMPL) \
- WINRT_EXCEPTION(NullReference, E_POINTER) \
- WINRT_EXCEPTION(ObjectDisposed, RO_E_CLOSED) \
- WINRT_EXCEPTION(OperationCanceled, E_ABORT) \
- WINRT_EXCEPTION(OutOfBounds, E_BOUNDS) \
- WINRT_EXCEPTION(OutOfMemory, E_OUTOFMEMORY) \
- WINRT_EXCEPTION(WrongThread, RPC_E_WRONG_THREAD)
+#define WINRT_EXCEPTION(name, hr) \
- void WINAPI __abi_WinRTraise##name##Exception(void) \
- { \
TRACE("()\n"); \__abi_WinRTraiseCOMException((hr)); \- }
It's mostly a matter of style but I would suggest to implement it the other way around. How about implementing __abi_WinRTraiseCOMException to call __abi_WinRTraise{ERROR}Exception functions (with the actual implementation in error specific functions)? Otherwise __abi_WinRTraiseCOMException will became a big function that would be good to divide into per-exception type helpers.