From f6f8b30c47bc28be5df692743fcf81c7952153ce Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Fri, 20 Aug 2021 18:44:38 +0200 Subject: [PATCH] msvcrt: Introduce macro for creating exception class. Signed-off-by: Piotr Caban Signed-off-by: Alexandre Julliard --- dlls/msvcrt/cpp.c | 192 ++++++---------------------------------- dlls/msvcrt/cppexcept.h | 101 +++++++++++++++++++-- 2 files changed, 121 insertions(+), 172 deletions(-) diff --git a/dlls/msvcrt/cpp.c b/dlls/msvcrt/cpp.c index 8d92f5763d3..980b580c71e 100644 --- a/dlls/msvcrt/cpp.c +++ b/dlls/msvcrt/cpp.c @@ -33,6 +33,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt); CREATE_TYPE_INFO_VTABLE +CREATE_EXCEPTION_OBJECT(exception) struct __type_info_node { @@ -44,7 +45,6 @@ typedef exception bad_cast; typedef exception bad_typeid; typedef exception __non_rtti_object; -extern const vtable_ptr exception_vtable; extern const vtable_ptr bad_typeid_vtable; extern const vtable_ptr bad_cast_vtable; extern const vtable_ptr __non_rtti_object_vtable; @@ -119,24 +119,6 @@ static void dump_obj_locator( const rtti_object_locator *ptr ) } #endif -/* Internal common ctor for exception */ -static void EXCEPTION_ctor(exception *_this, const char** name) -{ - _this->vtable = &exception_vtable; - if (*name) - { - unsigned int name_len = strlen(*name) + 1; - _this->name = 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.@) */ @@ -144,8 +126,7 @@ DEFINE_THISCALL_WRAPPER(exception_ctor,8) exception * __thiscall exception_ctor(exception * _this, const char ** name) { TRACE("(%p,%s)\n", _this, *name); - EXCEPTION_ctor(_this, name); - return _this; + return __exception_ctor(_this, *name, &exception_vtable); } /****************************************************************** @@ -161,48 +142,14 @@ exception * __thiscall exception_ctor_noalloc(exception * _this, char ** name, i return _this; } -/****************************************************************** - * ??0exception@@QAE@ABV0@@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(exception_copy_ctor,8) -exception * __thiscall exception_copy_ctor(exception * _this, const exception * rhs) -{ - TRACE("(%p,%p)\n", _this, rhs); - - if (!rhs->do_free) - { - _this->vtable = &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(exception_default_ctor,4) exception * __thiscall 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(exception_dtor,4) -void __thiscall exception_dtor(exception * _this) -{ - TRACE("(%p)\n", _this); - _this->vtable = &exception_vtable; - if (_this->do_free) free(_this->name); + return __exception_ctor(_this, NULL, &exception_vtable); } /****************************************************************** @@ -221,29 +168,6 @@ exception * __thiscall exception_opequals(exception * _this, const exception * r return _this; } -/****************************************************************** - * ??_Eexception@@UAEPAXI@Z (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(exception_vector_dtor,8) -void * __thiscall 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--) exception_dtor(_this + i); - operator_delete(ptr); - } - else - { - exception_dtor(_this); - if (flags & 1) operator_delete(_this); - } - return _this; -} - /****************************************************************** * ??_Gexception@@UAEPAXI@Z (MSVCRT.@) */ @@ -256,16 +180,6 @@ void * __thiscall exception_scalar_dtor(exception * _this, unsigned int flags) return _this; } -/****************************************************************** - * ?what@exception@@UBEPBDXZ (MSVCRT.@) - */ -DEFINE_THISCALL_WRAPPER(exception_what,4) -const char * __thiscall exception_what(exception * _this) -{ - TRACE("(%p) returning %s\n", _this, _this->name); - return _this->name ? _this->name : "Unknown exception"; -} - /****************************************************************** * ??0bad_typeid@@QAE@ABV0@@Z (MSVCRT.@) */ @@ -273,9 +187,7 @@ DEFINE_THISCALL_WRAPPER(bad_typeid_copy_ctor,8) bad_typeid * __thiscall bad_typeid_copy_ctor(bad_typeid * _this, const bad_typeid * rhs) { TRACE("(%p %p)\n", _this, rhs); - exception_copy_ctor(_this, rhs); - _this->vtable = &bad_typeid_vtable; - return _this; + return __exception_copy_ctor(_this, rhs, &bad_typeid_vtable); } /****************************************************************** @@ -285,9 +197,7 @@ DEFINE_THISCALL_WRAPPER(bad_typeid_ctor,8) bad_typeid * __thiscall bad_typeid_ctor(bad_typeid * _this, const char * name) { TRACE("(%p %s)\n", _this, name); - EXCEPTION_ctor(_this, &name); - _this->vtable = &bad_typeid_vtable; - return _this; + return __exception_ctor(_this, name, &bad_typeid_vtable); } /****************************************************************** @@ -362,10 +272,8 @@ DEFINE_THISCALL_WRAPPER(__non_rtti_object_copy_ctor,8) __non_rtti_object * __thiscall __non_rtti_object_copy_ctor(__non_rtti_object * _this, const __non_rtti_object * rhs) { - TRACE("(%p %p)\n", _this, rhs); - bad_typeid_copy_ctor(_this, rhs); - _this->vtable = &__non_rtti_object_vtable; - return _this; + TRACE("(%p %p)\n", _this, rhs); + return __exception_copy_ctor(_this, rhs, &__non_rtti_object_vtable); } /****************************************************************** @@ -376,9 +284,7 @@ __non_rtti_object * __thiscall __non_rtti_object_ctor(__non_rtti_object * _this, const char * name) { TRACE("(%p %s)\n", _this, name); - EXCEPTION_ctor(_this, &name); - _this->vtable = &__non_rtti_object_vtable; - return _this; + return __exception_ctor(_this, name, &__non_rtti_object_vtable); } /****************************************************************** @@ -446,9 +352,7 @@ DEFINE_THISCALL_WRAPPER(bad_cast_ctor,8) bad_cast * __thiscall bad_cast_ctor(bad_cast * _this, const char ** name) { TRACE("(%p %s)\n", _this, *name); - EXCEPTION_ctor(_this, name); - _this->vtable = &bad_cast_vtable; - return _this; + return __exception_ctor(_this, *name, &bad_cast_vtable); } /****************************************************************** @@ -458,9 +362,7 @@ DEFINE_THISCALL_WRAPPER(bad_cast_copy_ctor,8) bad_cast * __thiscall bad_cast_copy_ctor(bad_cast * _this, const bad_cast * rhs) { TRACE("(%p %p)\n", _this, rhs); - exception_copy_ctor(_this, rhs); - _this->vtable = &bad_cast_vtable; - return _this; + return __exception_copy_ctor(_this, rhs, &bad_cast_vtable); } /****************************************************************** @@ -470,9 +372,7 @@ DEFINE_THISCALL_WRAPPER(bad_cast_ctor_charptr,8) bad_cast * __thiscall bad_cast_ctor_charptr(bad_cast * _this, const char * name) { TRACE("(%p %s)\n", _this, name); - EXCEPTION_ctor(_this, &name); - _this->vtable = &bad_cast_vtable; - return _this; + return __exception_ctor(_this, name, &bad_cast_vtable); } /****************************************************************** @@ -632,20 +532,12 @@ const char * __thiscall type_info_raw_name(type_info * _this) typedef exception bad_alloc; extern const vtable_ptr bad_alloc_vtable; -static void bad_alloc_ctor(bad_alloc *this, const char **name) -{ - exception_ctor(this, name); - this->vtable = &bad_alloc_vtable; -} - /* bad_alloc class implementation */ DEFINE_THISCALL_WRAPPER(bad_alloc_copy_ctor,8) bad_alloc * __thiscall bad_alloc_copy_ctor(bad_alloc * _this, const bad_alloc * rhs) { TRACE("(%p %p)\n", _this, rhs); - exception_copy_ctor(_this, rhs); - _this->vtable = &bad_alloc_vtable; - return _this; + return __exception_copy_ctor(_this, rhs, &bad_alloc_vtable); } DEFINE_THISCALL_WRAPPER(bad_alloc_dtor,4) @@ -672,8 +564,7 @@ scheduler_resource_allocation_error* __thiscall scheduler_resource_allocation_er scheduler_resource_allocation_error *this, const char *name, HRESULT hr) { TRACE("(%p %s %x)\n", this, wine_dbgstr_a(name), hr); - exception_ctor(&this->e, &name); - this->e.vtable = &scheduler_resource_allocation_error_vtable; + __exception_ctor(&this->e, name, &scheduler_resource_allocation_error_vtable); this->hr = hr; return this; } @@ -720,9 +611,7 @@ 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); - exception_ctor(this, &str); - this->vtable = &improper_lock_vtable; - return this; + return __exception_ctor(this, str, &improper_lock_vtable); } /* ??0improper_lock@Concurrency@@QAE@XZ */ @@ -737,9 +626,7 @@ DEFINE_THISCALL_WRAPPER(improper_lock_copy_ctor,8) improper_lock * __thiscall improper_lock_copy_ctor(improper_lock * _this, const improper_lock * rhs) { TRACE("(%p %p)\n", _this, rhs); - exception_copy_ctor(_this, rhs); - _this->vtable = &improper_lock_vtable; - return _this; + return __exception_copy_ctor(_this, rhs, &improper_lock_vtable); } typedef exception invalid_scheduler_policy_key; @@ -752,9 +639,7 @@ 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); - exception_ctor(this, &str); - this->vtable = &invalid_scheduler_policy_key_vtable; - return this; + return __exception_ctor(this, str, &invalid_scheduler_policy_key_vtable); } /* ??0invalid_scheduler_policy_key@Concurrency@@QAE@XZ */ @@ -771,9 +656,7 @@ invalid_scheduler_policy_key * __thiscall invalid_scheduler_policy_key_copy_ctor invalid_scheduler_policy_key * _this, const invalid_scheduler_policy_key * rhs) { TRACE("(%p %p)\n", _this, rhs); - exception_copy_ctor(_this, rhs); - _this->vtable = &invalid_scheduler_policy_key_vtable; - return _this; + return __exception_copy_ctor(_this, rhs, &invalid_scheduler_policy_key_vtable); } typedef exception invalid_scheduler_policy_value; @@ -786,9 +669,7 @@ invalid_scheduler_policy_value* __thiscall invalid_scheduler_policy_value_ctor_s invalid_scheduler_policy_value *this, const char *str) { TRACE("(%p %p)\n", this, str); - exception_ctor(this, &str); - this->vtable = &invalid_scheduler_policy_value_vtable; - return this; + return __exception_ctor(this, str, &invalid_scheduler_policy_value_vtable); } /* ??0invalid_scheduler_policy_value@Concurrency@@QAE@XZ */ @@ -805,9 +686,7 @@ invalid_scheduler_policy_value * __thiscall invalid_scheduler_policy_value_copy_ invalid_scheduler_policy_value * _this, const invalid_scheduler_policy_value * rhs) { TRACE("(%p %p)\n", _this, rhs); - exception_copy_ctor(_this, rhs); - _this->vtable = &invalid_scheduler_policy_value_vtable; - return _this; + return __exception_copy_ctor(_this, rhs, &invalid_scheduler_policy_value_vtable); } typedef exception invalid_scheduler_policy_thread_specification; @@ -820,9 +699,7 @@ invalid_scheduler_policy_thread_specification* __thiscall invalid_scheduler_poli invalid_scheduler_policy_thread_specification *this, const char *str) { TRACE("(%p %p)\n", this, str); - exception_ctor(this, &str); - this->vtable = &invalid_scheduler_policy_thread_specification_vtable; - return this; + return __exception_ctor(this, str, &invalid_scheduler_policy_thread_specification_vtable); } /* ??0invalid_scheduler_policy_thread_specification@Concurrency@@QAE@XZ */ @@ -839,9 +716,7 @@ invalid_scheduler_policy_thread_specification * __thiscall invalid_scheduler_pol invalid_scheduler_policy_thread_specification * _this, const invalid_scheduler_policy_thread_specification * rhs) { TRACE("(%p %p)\n", _this, rhs); - exception_copy_ctor(_this, rhs); - _this->vtable = &invalid_scheduler_policy_thread_specification_vtable; - return _this; + return __exception_copy_ctor(_this, rhs, &invalid_scheduler_policy_thread_specification_vtable); } typedef exception improper_scheduler_attach; @@ -854,9 +729,7 @@ improper_scheduler_attach* __thiscall improper_scheduler_attach_ctor_str( improper_scheduler_attach *this, const char *str) { TRACE("(%p %p)\n", this, str); - exception_ctor(this, &str); - this->vtable = &improper_scheduler_attach_vtable; - return this; + return __exception_ctor(this, str, &improper_scheduler_attach_vtable); } /* ??0improper_scheduler_attach@Concurrency@@QAE@XZ */ @@ -873,9 +746,7 @@ improper_scheduler_attach * __thiscall improper_scheduler_attach_copy_ctor( improper_scheduler_attach * _this, const improper_scheduler_attach * rhs) { TRACE("(%p %p)\n", _this, rhs); - exception_copy_ctor(_this, rhs); - _this->vtable = &improper_scheduler_attach_vtable; - return _this; + return __exception_copy_ctor(_this, rhs, &improper_scheduler_attach_vtable); } typedef exception improper_scheduler_detach; @@ -888,9 +759,7 @@ improper_scheduler_detach* __thiscall improper_scheduler_detach_ctor_str( improper_scheduler_detach *this, const char *str) { TRACE("(%p %p)\n", this, str); - exception_ctor(this, &str); - this->vtable = &improper_scheduler_detach_vtable; - return this; + return __exception_ctor(this, str, &improper_scheduler_detach_vtable); } /* ??0improper_scheduler_detach@Concurrency@@QAE@XZ */ @@ -907,18 +776,13 @@ improper_scheduler_detach * __thiscall improper_scheduler_detach_copy_ctor( improper_scheduler_detach * _this, const improper_scheduler_detach * rhs) { TRACE("(%p %p)\n", _this, rhs); - exception_copy_ctor(_this, rhs); - _this->vtable = &improper_scheduler_detach_vtable; - return _this; + return __exception_copy_ctor(_this, rhs, &improper_scheduler_detach_vtable); } #endif /* _MSVCR_VER >= 100 */ __ASM_BLOCK_BEGIN(vtables) -__ASM_VTABLE(exception, - VTABLE_ADD_FUNC(exception_vector_dtor) - VTABLE_ADD_FUNC(exception_what)); #if _MSVCR_VER >= 80 __ASM_VTABLE(exception_old, VTABLE_ADD_FUNC(exception_vector_dtor) @@ -963,14 +827,12 @@ __ASM_VTABLE(improper_scheduler_detach, __ASM_BLOCK_END #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@@" ) @@ -991,7 +853,7 @@ DEFINE_RTTI_DATA1(improper_scheduler_detach, 0, &exception_rtti_base_descriptor, ".?AVimproper_scheduler_detach@Concurrency@@" ) #endif -DEFINE_CXX_DATA0( exception, exception_dtor ) +DEFINE_CXX_EXCEPTION0( exception, exception_dtor ) DEFINE_CXX_DATA1( bad_typeid, &exception_cxx_type_info, bad_typeid_dtor ) DEFINE_CXX_DATA1( bad_cast, &exception_cxx_type_info, bad_cast_dtor ) DEFINE_CXX_DATA2( __non_rtti_object, &bad_typeid_cxx_type_info, @@ -1056,7 +918,7 @@ 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); + __exception_ctor(&e, str, &bad_alloc_vtable); _CxxThrowException(&e, &bad_alloc_exception_type); } #if _MSVCR_VER >= 100 diff --git a/dlls/msvcrt/cppexcept.h b/dlls/msvcrt/cppexcept.h index 2792491ca7f..f6593d87607 100644 --- a/dlls/msvcrt/cppexcept.h +++ b/dlls/msvcrt/cppexcept.h @@ -165,9 +165,7 @@ static const cxx_type_info type ## _cxx_type_info = { \ (cxx_copy_ctor)THISCALL(type ##_copy_ctor) \ }; -#define DEFINE_CXX_DATA(type, base_no, cl1, cl2, dtor) \ -DEFINE_CXX_TYPE_INFO(type) \ -\ +#define DEFINE_CXX_EXCEPTION(type, base_no, cl1, cl2, dtor) \ static const cxx_type_info_table type ## _cxx_type_table = { \ base_no+1, \ { \ @@ -201,10 +199,7 @@ static void init_ ## type ## _cxx_type_info(char *base) \ type ## _cxx_type_info.copy_ctor = (char *)type ## _copy_ctor - base; \ } -#define DEFINE_CXX_DATA(type, base_no, cl1, cl2, dtor) \ -\ -DEFINE_CXX_TYPE_INFO(type) \ -\ +#define DEFINE_CXX_EXCEPTION(type, base_no, cl1, cl2, dtor) \ static cxx_type_info_table type ## _cxx_type_table = { \ base_no+1, \ { \ @@ -230,8 +225,16 @@ static void init_ ## type ## _cxx(char *base) \ type ## _exception_type.destructor = (char *)dtor - base; \ type ## _exception_type.type_info_table = (char *)&type ## _cxx_type_table - base; \ } + #endif +#define DEFINE_CXX_DATA(type, base_no, cl1, cl2, dtor) \ +DEFINE_CXX_TYPE_INFO(type) \ +DEFINE_CXX_EXCEPTION(type, base_no, cl1, cl2, dtor) + +#define DEFINE_CXX_EXCEPTION0(name, dtor) \ + DEFINE_CXX_EXCEPTION(name, 0, NULL, NULL, dtor) + #define DEFINE_CXX_DATA0(name, dtor) \ DEFINE_CXX_DATA(name, 0, NULL, NULL, dtor) #define DEFINE_CXX_DATA1(name, cl1, dtor) \ @@ -239,4 +242,88 @@ static void init_ ## type ## _cxx(char *base) \ #define DEFINE_CXX_DATA2(name, cl1, cl2, dtor) \ DEFINE_CXX_DATA(name, 2, cl1, cl2, dtor) +#if _MSVCR_VER >= 80 +#define EXCEPTION_MANGLED_NAME ".?AVexception@std@@" +#else +#define EXCEPTION_MANGLED_NAME ".?AVexception@@" +#endif + +#define CREATE_EXCEPTION_OBJECT(exception_name) \ +static exception* __exception_ctor(exception *this, const char *str, const vtable_ptr *vtbl) \ +{ \ + if (str) \ + { \ + unsigned int len = strlen(str) + 1; \ + this->name = malloc(len); \ + memcpy(this->name, str, len); \ + this->do_free = TRUE; \ + } \ + else \ + { \ + this->name = NULL; \ + this->do_free = FALSE; \ + } \ + this->vtable = vtbl; \ + return this; \ +} \ +\ +static exception* __exception_copy_ctor(exception *this, const exception *rhs, const vtable_ptr *vtbl) \ +{ \ + if (rhs->do_free) \ + { \ + __exception_ctor(this, rhs->name, vtbl); \ + } \ + else \ + { \ + *this = *rhs; \ + this->vtable = vtbl; \ + } \ + return this; \ +} \ +extern const vtable_ptr exception_name ## _vtable; \ +DEFINE_THISCALL_WRAPPER(exception_name ## _copy_ctor,8) \ +exception* __thiscall exception_name ## _copy_ctor(exception *this, const exception *rhs) \ +{ \ + return __exception_copy_ctor(this, rhs, & exception_name ## _vtable); \ +} \ +\ +DEFINE_THISCALL_WRAPPER(exception_name ## _dtor,4) \ +void __thiscall exception_name ## _dtor(exception *this) \ +{ \ + if (this->do_free) free(this->name); \ +} \ +\ +DEFINE_THISCALL_WRAPPER(exception_name ## _vector_dtor,8) \ +void* __thiscall exception_name ## _vector_dtor(exception *this, unsigned int flags) \ +{ \ + if (flags & 2) \ + { \ + INT_PTR i, *ptr = (INT_PTR *)this - 1; \ +\ + for (i = *ptr - 1; i >= 0; i--) exception_name ## _dtor(this + i); \ + operator_delete(ptr); \ + } \ + else \ + { \ + exception_name ## _dtor(this); \ + if (flags & 1) operator_delete(this); \ + } \ + return this; \ +} \ +\ +DEFINE_THISCALL_WRAPPER(exception_name ## _what,4) \ +const char* __thiscall exception_name ## _what(exception *this) \ +{ \ + return this->name ? this->name : "Unknown exception"; \ +} \ +\ +__ASM_BLOCK_BEGIN(exception_name ## _vtables) \ +__ASM_VTABLE(exception_name, \ + VTABLE_ADD_FUNC(exception_name ## _vector_dtor) \ + VTABLE_ADD_FUNC(exception_name ## _what)); \ +__ASM_BLOCK_END \ +\ +DEFINE_RTTI_DATA0(exception_name, 0, EXCEPTION_MANGLED_NAME) \ +DEFINE_CXX_TYPE_INFO(exception_name) + #endif /* __MSVCRT_CPPEXCEPT_H */