From: Piotr Caban piotr@codeweavers.com
--- dlls/vccorlib140/cxx.h | 40 ++++++++++++++++++++++------- dlls/vccorlib140/except.c | 53 ++++++++++++++++++++++++++++++++++----- 2 files changed, 78 insertions(+), 15 deletions(-)
diff --git a/dlls/vccorlib140/cxx.h b/dlls/vccorlib140/cxx.h index 94721a9d686..a114b5fc07a 100644 --- a/dlls/vccorlib140/cxx.h +++ b/dlls/vccorlib140/cxx.h @@ -68,11 +68,14 @@
#ifndef RTTI_USE_RVA
-#define DEFINE_RTTI_DATA(name, off, mangled_name, ...) \ +#define DEFINE_RTTI_BASE(name, this_off, base_classes, mangled_name) \ static type_info name ## _type_info = { &type_info_vtable, NULL, mangled_name }; \ \ static const rtti_base_descriptor name ## _rtti_base_descriptor[1] = \ - { { &name ##_type_info, ARRAY_SIZE(((const void *[]){ __VA_ARGS__ })), { 0, -1, 0}, 64 } }; \ + { { &name ##_type_info, base_classes, { this_off, -1, 0}, 64 } }; + +#define DEFINE_RTTI_DATA(name, off, mangled_name, ...) \ +DEFINE_RTTI_BASE(name, 0, ARRAY_SIZE(((const void *[]){ __VA_ARGS__ })), mangled_name ) \ \ static const rtti_base_array name ## _rtti_base_array = \ { { name ## _rtti_base_descriptor, __VA_ARGS__ } }; \ @@ -83,20 +86,29 @@ static const rtti_object_hierarchy name ## _hierarchy = \ const rtti_object_locator name ## _rtti = \ { 0, off, 0, &name ## _type_info, &name ## _hierarchy };
+#define INIT_RTTI_BASE(name,base) /* nothing to do */ #define INIT_RTTI(name,base) /* nothing to do */
#elif defined __WINE_PE_BUILD
-#define DEFINE_RTTI_DATA2(name, off, mangled_name, ...) \ -extern const rtti_object_locator name##_rtti; \ +#define DEFINE_RTTI_BASE(name, this_off, base_classes, mangled_name) \ type_info name ## _type_info = { &type_info_vtable, NULL, mangled_name }; \ extern const rtti_base_descriptor name ## _rtti_base_descriptor[1]; \ -void __asm_dummy_ ## name ## _rtti(void) \ +void __asm_dummy_ ## name ## _rtti_base(void) \ { \ asm( ".balign 4\n\t" \ __ASM_GLOBL(#name "_rtti_base_descriptor") "\n\t" \ ".rva " #name "_type_info\n\t" \ - ".long %c0-1, 0, -1, 0, 64\n" \ + ".long %c0, %c1, -1, 0, 64\n" \ + :: "i"(base_classes), "i"(this_off) ); \ +} + +#define DEFINE_RTTI_DATA2(name, off, mangled_name, ...) \ +extern const rtti_object_locator name##_rtti; \ +DEFINE_RTTI_BASE(name, 0, ARRAY_SIZE(((const void *[]){ __VA_ARGS__ }))-1, mangled_name) \ +void __asm_dummy_ ## name ## _rtti(void) \ +{ \ + asm( ".balign 4\n\t" \ #name "_rtti_base_array:\n\t" \ ".rva " #__VA_ARGS__ "\n" \ #name "_rtti_hierarchy:\n\t" \ @@ -112,15 +124,24 @@ void __asm_dummy_ ## name ## _rtti(void) \ #define DEFINE_RTTI_DATA(name, off, mangled_name, ...) \ DEFINE_RTTI_DATA2(name, off, mangled_name, name ## _rtti_base_descriptor, ##__VA_ARGS__)
+#define INIT_RTTI_BASE(name,base) /* nothing to do */ #define INIT_RTTI(name,base) /* nothing to do */
#else /* RTTI_USE_RVA */
-#define DEFINE_RTTI_DATA(name, off, mangled_name, ...) \ +#define DEFINE_RTTI_BASE(name, this_off, base_classes, mangled_name) \ static type_info name ## _type_info = { &type_info_vtable, NULL, mangled_name }; \ \ static rtti_base_descriptor name ## _rtti_base_descriptor[1] = \ - { { 0xdeadbeef, ARRAY_SIZE(((const void *[]){ __VA_ARGS__ })), { 0, -1, 0}, 64 } }; \ + { { 0xdeadbeef, base_classes, { this_off, -1, 0}, 64 } }; \ +\ +static void init_ ## name ## _rtti_base(char *base) \ +{ \ + name ## _rtti_base_descriptor[0].type_descriptor = (char*)&name ## _type_info - base; \ +} + +#define DEFINE_RTTI_DATA(name, off, mangled_name, ...) \ +DEFINE_RTTI_BASE(name, 0, ARRAY_SIZE(((const void *[]){ __VA_ARGS__ })), mangled_name); \ \ static rtti_base_array name ## _rtti_base_array; \ \ @@ -133,7 +154,7 @@ rtti_object_locator name ## _rtti = \ static void init_ ## name ## _rtti(char *base) \ { \ const void * const name ## _rtti_bases[] = { name ## _rtti_base_descriptor, __VA_ARGS__ }; \ - name ## _rtti_base_descriptor[0].type_descriptor = (char*)&name ## _type_info - base; \ + init_ ## name ## _rtti_base(base); \ for (unsigned int i = 0; i < ARRAY_SIZE(name ## _rtti_bases); i++) \ name ## _rtti_base_array.bases[i] = (char*)name ## _rtti_bases[i] - base; \ name ## _hierarchy.base_classes = (char*)&name ## _rtti_base_array - base; \ @@ -142,6 +163,7 @@ static void init_ ## name ## _rtti(char *base) \ name ## _rtti.object_locator = (char*)&name ## _rtti - base; \ }
+#define INIT_RTTI_BASE(name,base) init_ ## name ## _rtti_base((void *)(base)) #define INIT_RTTI(name,base) init_ ## name ## _rtti((void *)(base))
#endif /* RTTI_USE_RVA */ diff --git a/dlls/vccorlib140/except.c b/dlls/vccorlib140/except.c index 3945d268b28..89d21f25aac 100644 --- a/dlls/vccorlib140/except.c +++ b/dlls/vccorlib140/except.c @@ -205,7 +205,18 @@ DEFINE_RTTI_DATA(Exception_ref, 0, EXCEPTION_REF_NAME()); typedef struct Exception *Exception_ref; DEFINE_CXX_TYPE(Exception_ref);
-DEFINE_RTTI_DATA(Exception, 0, "?.AVException@Platform@@"); +DEFINE_RTTI_BASE(Exception_IClosable, offsetof(struct Exception, IClosable_iface), + 1, ".?AUIDisposable@Platform@@"); +DEFINE_RTTI_BASE(Exception_IEquatable, offsetof(struct Exception, IEquatable_iface), + 1, ".?AUIEquatable@Details@Platform@@"); +DEFINE_RTTI_BASE(Exception_IPrintable, offsetof(struct Exception, IPrintable_iface), + 1, ".?AUIPrintable@Details@Platform@@"); +DEFINE_RTTI_BASE(Exception_Object, 0, 0, ".?AVObject@Platform@@"); +DEFINE_RTTI_DATA(Exception, 0, ".?AVException@Platform@@", + Exception_Object_rtti_base_descriptor, + Exception_IPrintable_rtti_base_descriptor, + Exception_IEquatable_rtti_base_descriptor, + Exception_IClosable_rtti_base_descriptor); COM_VTABLE_RTTI_START(IInspectable, Exception) COM_VTABLE_ENTRY(Exception_QueryInterface) COM_VTABLE_ENTRY(Exception_AddRef) @@ -225,7 +236,11 @@ static HRESULT WINAPI Exception_Closable_Close(IClosable *iface) }
DEFINE_RTTI_DATA(Exception_Closable, offsetof(struct Exception, IClosable_iface), - "?.AVException@Platform@@") + ".?AVException@Platform@@", + Exception_Object_rtti_base_descriptor, + Exception_IPrintable_rtti_base_descriptor, + Exception_IEquatable_rtti_base_descriptor, + Exception_IClosable_rtti_base_descriptor) COM_VTABLE_RTTI_START(IClosable, Exception_Closable) COM_VTABLE_ENTRY(Exception_Closable_QueryInterface) COM_VTABLE_ENTRY(Exception_Closable_AddRef) @@ -303,7 +318,12 @@ DEFINE_RTTI_DATA(COMException_ref, 0, EXCEPTION_REF_NAME(COM), Exception_ref_rtt typedef struct Exception *COMException_ref; DEFINE_CXX_TYPE(COMException_ref, Exception_ref_cxx_type_info);
-DEFINE_RTTI_DATA(COMException, 0, ".?AVCOMException@Platform@@"); +DEFINE_RTTI_DATA(COMException, 0, ".?AVCOMException@Platform@@", + Exception_rtti_base_descriptor, + Exception_Object_rtti_base_descriptor, + Exception_IPrintable_rtti_base_descriptor, + Exception_IEquatable_rtti_base_descriptor, + Exception_IClosable_rtti_base_descriptor); COM_VTABLE_RTTI_START(IInspectable, COMException) COM_VTABLE_ENTRY(Exception_QueryInterface) COM_VTABLE_ENTRY(Exception_AddRef) @@ -314,7 +334,12 @@ COM_VTABLE_ENTRY(Exception_GetTrustLevel) COM_VTABLE_RTTI_END;
DEFINE_RTTI_DATA(COMException_Closable, offsetof(struct Exception, IClosable_iface), - ".?AVCOMException@Platform@@") + ".?AVCOMException@Platform@@", + Exception_rtti_base_descriptor, + Exception_Object_rtti_base_descriptor, + Exception_IPrintable_rtti_base_descriptor, + Exception_IEquatable_rtti_base_descriptor, + Exception_IClosable_rtti_base_descriptor) COM_VTABLE_RTTI_START(IClosable, COMException_Closable) COM_VTABLE_ENTRY(Exception_Closable_QueryInterface) COM_VTABLE_ENTRY(Exception_Closable_AddRef) @@ -356,7 +381,13 @@ struct Exception *__cdecl COMException_hstring_ctor(struct Exception *this, HRES DEFINE_CXX_TYPE(name##Exception_ref, COMException_ref_cxx_type_info, \ Exception_ref_cxx_type_info); \ \ - DEFINE_RTTI_DATA(name##Exception, 0, ".?AV" #name "Exception@Platform@@"); \ + DEFINE_RTTI_DATA(name##Exception, 0, ".?AV" #name "Exception@Platform@@", \ + COMException_rtti_base_descriptor, \ + Exception_rtti_base_descriptor, \ + Exception_Object_rtti_base_descriptor, \ + Exception_IPrintable_rtti_base_descriptor, \ + Exception_IEquatable_rtti_base_descriptor, \ + Exception_IClosable_rtti_base_descriptor); \ COM_VTABLE_RTTI_START(IInspectable, name##Exception) \ COM_VTABLE_ENTRY(Exception_QueryInterface) \ COM_VTABLE_ENTRY(Exception_AddRef) \ @@ -367,7 +398,13 @@ struct Exception *__cdecl COMException_hstring_ctor(struct Exception *this, HRES COM_VTABLE_RTTI_END; \ \ DEFINE_RTTI_DATA(name##Exception_Closable, offsetof(struct Exception, IClosable_iface), \ - ".?AV" #name "Exception@Platform@@"); \ + ".?AV" #name "Exception@Platform@@", \ + COMException_rtti_base_descriptor, \ + Exception_rtti_base_descriptor, \ + Exception_Object_rtti_base_descriptor, \ + Exception_IPrintable_rtti_base_descriptor, \ + Exception_IEquatable_rtti_base_descriptor, \ + Exception_IClosable_rtti_base_descriptor); \ COM_VTABLE_RTTI_START(IClosable, name##Exception_Closable) \ COM_VTABLE_ENTRY(Exception_Closable_QueryInterface) \ COM_VTABLE_ENTRY(Exception_Closable_AddRef) \ @@ -499,6 +536,10 @@ void init_exception(void *base) { INIT_RTTI(Exception_ref, base); INIT_CXX_TYPE(Exception_ref, base); + INIT_RTTI_BASE(Exception_IClosable, base); + INIT_RTTI_BASE(Exception_IEquatable, base); + INIT_RTTI_BASE(Exception_IPrintable, base); + INIT_RTTI_BASE(Exception_Object, base); INIT_RTTI(Exception, base); INIT_RTTI(Exception_Closable, base);
From: Piotr Caban piotr@codeweavers.com
--- dlls/vccorlib140/cxx.h | 38 ++++++++++++++++++-- dlls/vccorlib140/except.c | 58 ++++++++++++++++++++++++------- dlls/vccorlib140/tests/vccorlib.c | 2 +- 3 files changed, 81 insertions(+), 17 deletions(-)
diff --git a/dlls/vccorlib140/cxx.h b/dlls/vccorlib140/cxx.h index a114b5fc07a..1834f77f03e 100644 --- a/dlls/vccorlib140/cxx.h +++ b/dlls/vccorlib140/cxx.h @@ -180,7 +180,13 @@ static const cxx_type_info_table type ## _cxx_type_table = \ static const cxx_exception_type type ## _exception_type = \ { TYPE_FLAG_WINRT, NULL, NULL, & type ## _cxx_type_table };
-#define INIT_CXX_TYPE(name,base) (void)name ## _exception_type +#define DEFINE_CXX_BASE(type, flags, off, mangled_name) \ +static type_info type ## _type_info = { &type_info_vtable, NULL, mangled_name }; \ +static const cxx_type_info type ## _cxx_type_info[1] = \ + { { flags, &type ##_type_info, { off, -1, 0 }, sizeof(void*), NULL } }; + +#define INIT_CXX_TYPE(name,base) /* nothing to do */ +#define INIT_CXX_BASE(name,base) /* nothing to do */
#elif defined __WINE_PE_BUILD
@@ -208,7 +214,22 @@ void __asm_dummy_ ## type ## _exception_type(void) \ #define DEFINE_CXX_TYPE(type, ...) \ DEFINE_CXX_TYPE2(type, type ## _cxx_type_info, ##__VA_ARGS__)
+#define DEFINE_CXX_BASE(type, flags, off, mangled_name) \ +type_info type ## _type_info = { &type_info_vtable, NULL, mangled_name }; \ +extern const cxx_type_info type ## _cxx_type_info[1]; \ +void __asm_dummy_ ## type ## _exception_type(void) \ +{\ + asm( ".balign 4\n\t" \ + __ASM_GLOBL(#type "_cxx_type_info") "\n\t" \ + ".long %c0\n\t" \ + ".rva " #type "_type_info\n\t" \ + ".long %c1, -1, 0, %c2\n\t" \ + ".long 0\n\t" \ + :: "i"(flags), "i"(off), "i"(sizeof(void *)) ); \ +} + #define INIT_CXX_TYPE(name,base) /* nothing to do */ +#define INIT_CXX_BASE(name,base) /* nothing to do */
#else /* CXX_USE_RVA */
@@ -228,7 +249,18 @@ static void init_ ## type ## _cxx(char *base) \ type ## _exception_type.type_info_table = (char *)&type ## _cxx_type_table - base; \ }
+#define DEFINE_CXX_BASE(type, flags, off, mangled_name) \ +static type_info type ## _type_info = { &type_info_vtable, NULL, mangled_name }; \ +static cxx_type_info type ## _cxx_type_info[1] = \ + { { flags, 0xdeadbeef, { off, -1, 0 }, sizeof(void *), 0 } }; \ +\ +static void init_ ## type ## _cxx_base(char *base) \ +{ \ + type ## _cxx_type_info[0].type_info = (char *)&type ## _type_info - base; \ +} + #define INIT_CXX_TYPE(name,base) init_ ## name ## _cxx((void *)(base)) +#define INIT_CXX_BASE(name,base) init_ ## name ## _cxx_base((void *)(base))
#endif /* CXX_USE_RVA */
@@ -364,7 +396,7 @@ typedef struct typedef struct { UINT count; - const cxx_type_info *info[5]; + const cxx_type_info *info[10]; } cxx_type_info_table;
typedef struct @@ -389,7 +421,7 @@ typedef struct typedef struct { UINT count; - unsigned int info[5]; + unsigned int info[10]; } cxx_type_info_table;
typedef struct diff --git a/dlls/vccorlib140/except.c b/dlls/vccorlib140/except.c index 89d21f25aac..e8b65d47237 100644 --- a/dlls/vccorlib140/except.c +++ b/dlls/vccorlib140/except.c @@ -37,11 +37,14 @@ extern void WINAPI DECLSPEC_NORETURN _CxxThrowException(void *, const cxx_except extern const void **__cdecl __current_exception(void);
#ifdef _WIN64 -#define EXCEPTION_REF_NAME(name) ".PE$AAV" #name "Exception@Platform@@" +#define REF_NAME(name) ".PE" name #else -#define EXCEPTION_REF_NAME(name) ".P$AAV" #name "Exception@Platform@@" +#define REF_NAME(name) ".P" name #endif
+#define CLASS_REF_NAME(name) REF_NAME("$AAV" name "@Platform@@") +#define INTERFACE_REF_NAME(name) REF_NAME("$AAU" name "@Platform@@") + /* Data members of the "Exception" C++/CX class. * A back-pointer to this struct is stored just before the IInspectable vtable of an Exception object. * TODO: The message fields are likely obtained from IRestrictedErrorInfo::GetErrorDetails, so we @@ -201,9 +204,24 @@ static HRESULT WINAPI Exception_GetTrustLevel(IInspectable *iface, TrustLevel *l return E_NOTIMPL; }
-DEFINE_RTTI_DATA(Exception_ref, 0, EXCEPTION_REF_NAME()); +DEFINE_CXX_BASE(Exception_void_ref, CLASS_IS_SIMPLE_TYPE, + 0, REF_NAME("AX")); +DEFINE_CXX_BASE(Exception_IClosable_ref, CLASS_IS_SIMPLE_TYPE | CLASS_IS_WINRT, + offsetof(struct Exception, IClosable_iface), INTERFACE_REF_NAME("IDisposable")); +DEFINE_CXX_BASE(Exception_IEquatable_ref, CLASS_IS_SIMPLE_TYPE | CLASS_IS_WINRT, + offsetof(struct Exception, IEquatable_iface), INTERFACE_REF_NAME("IEquatable")); +DEFINE_CXX_BASE(Exception_IPrintable_ref, CLASS_IS_SIMPLE_TYPE | CLASS_IS_WINRT, + offsetof(struct Exception, IPrintable_iface), INTERFACE_REF_NAME("IPrintable")); +DEFINE_CXX_BASE(Exception_Object_ref, CLASS_IS_SIMPLE_TYPE | CLASS_IS_WINRT, + 0, CLASS_REF_NAME("Object")); +type_info Exception_ref_type_info = { &type_info_vtable, NULL, CLASS_REF_NAME("Exception") }; typedef struct Exception *Exception_ref; -DEFINE_CXX_TYPE(Exception_ref); +DEFINE_CXX_TYPE(Exception_ref, + Exception_Object_ref_cxx_type_info, + Exception_IPrintable_ref_cxx_type_info, + Exception_IEquatable_ref_cxx_type_info, + Exception_IClosable_ref_cxx_type_info, + Exception_void_ref_cxx_type_info);
DEFINE_RTTI_BASE(Exception_IClosable, offsetof(struct Exception, IClosable_iface), 1, ".?AUIDisposable@Platform@@"); @@ -314,9 +332,15 @@ struct Exception *__cdecl Exception_hstring_ctor(struct Exception *this, HRESULT return this; }
-DEFINE_RTTI_DATA(COMException_ref, 0, EXCEPTION_REF_NAME(COM), Exception_ref_rtti_base_descriptor); +type_info COMException_ref_type_info = { &type_info_vtable, NULL, CLASS_REF_NAME("COMException") }; typedef struct Exception *COMException_ref; -DEFINE_CXX_TYPE(COMException_ref, Exception_ref_cxx_type_info); +DEFINE_CXX_TYPE(COMException_ref, + Exception_ref_cxx_type_info, + Exception_Object_ref_cxx_type_info, + Exception_IPrintable_ref_cxx_type_info, + Exception_IEquatable_ref_cxx_type_info, + Exception_IClosable_ref_cxx_type_info, + Exception_void_ref_cxx_type_info);
DEFINE_RTTI_DATA(COMException, 0, ".?AVCOMException@Platform@@", Exception_rtti_base_descriptor, @@ -375,11 +399,17 @@ struct Exception *__cdecl COMException_hstring_ctor(struct Exception *this, HRES }
#define WINRT_EXCEPTION(name, hr) \ - DEFINE_RTTI_DATA(name##Exception_ref, 0, EXCEPTION_REF_NAME(name), \ - COMException_ref_rtti_base_descriptor, Exception_ref_rtti_base_descriptor); \ + type_info name ## Exception_ref ## _type_info = \ + { &type_info_vtable, NULL, CLASS_REF_NAME(#name "Exception") }; \ typedef COMException_ref name##Exception_ref; \ - DEFINE_CXX_TYPE(name##Exception_ref, COMException_ref_cxx_type_info, \ - Exception_ref_cxx_type_info); \ + DEFINE_CXX_TYPE(name##Exception_ref, \ + COMException_ref_cxx_type_info, \ + Exception_ref_cxx_type_info, \ + Exception_Object_ref_cxx_type_info, \ + Exception_IPrintable_ref_cxx_type_info, \ + Exception_IEquatable_ref_cxx_type_info, \ + Exception_IClosable_ref_cxx_type_info, \ + Exception_void_ref_cxx_type_info); \ \ DEFINE_RTTI_DATA(name##Exception, 0, ".?AV" #name "Exception@Platform@@", \ COMException_rtti_base_descriptor, \ @@ -534,7 +564,11 @@ HSTRING __cdecl Exception_get_Message(struct Exception *this)
void init_exception(void *base) { - INIT_RTTI(Exception_ref, base); + INIT_CXX_BASE(Exception_void_ref, base); + INIT_CXX_BASE(Exception_IClosable_ref, base); + INIT_CXX_BASE(Exception_IEquatable_ref, base); + INIT_CXX_BASE(Exception_IPrintable_ref, base); + INIT_CXX_BASE(Exception_Object_ref, base); INIT_CXX_TYPE(Exception_ref, base); INIT_RTTI_BASE(Exception_IClosable, base); INIT_RTTI_BASE(Exception_IEquatable, base); @@ -543,13 +577,11 @@ void init_exception(void *base) INIT_RTTI(Exception, base); INIT_RTTI(Exception_Closable, base);
- INIT_RTTI(COMException_ref, base); INIT_CXX_TYPE(COMException_ref, base); INIT_RTTI(COMException, base); INIT_RTTI(COMException_Closable, base);
#define WINRT_EXCEPTION(name, hr) \ - INIT_RTTI(name##Exception_ref, base); \ INIT_CXX_TYPE(name##Exception_ref, base); \ INIT_RTTI(name##Exception, base); \ INIT_RTTI(name##Exception_Closable, base); diff --git a/dlls/vccorlib140/tests/vccorlib.c b/dlls/vccorlib140/tests/vccorlib.c index c4f669d8190..03ded3fafcb 100644 --- a/dlls/vccorlib140/tests/vccorlib.c +++ b/dlls/vccorlib140/tests/vccorlib.c @@ -1509,7 +1509,7 @@ static void test_exceptions(void)
cxx_info = (cxx_type_info *)(base + type_info_table->info[j]); if (j == type_info_table->count - 1) - todo_wine ok(cxx_info->flags == CLASS_IS_SIMPLE_TYPE, "got flags %u\n", cxx_info->flags); + ok(cxx_info->flags == CLASS_IS_SIMPLE_TYPE, "got flags %u\n", cxx_info->flags); else ok(cxx_info->flags == (CLASS_IS_SIMPLE_TYPE | CLASS_IS_IUNKNOWN), "got flags %u\n", cxx_info->flags); ok(cxx_info->size == sizeof(void *), "got size %u\n", cxx_info->size);
This merge request was approved by Vibhav Pant.