From 5199a8c92315272fe87c7fce898bee583abe9af3 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Thu, 7 May 2020 10:24:20 -0700 Subject: [PATCH] Use C++11 alias templates instead of macro-defined types to implement specialized holder wrappers. (#35863) --- src/coreclr/src/debug/di/process.cpp | 3 +- src/coreclr/src/inc/appxutil.h | 2 - src/coreclr/src/inc/ex.h | 8 +- src/coreclr/src/inc/holder.h | 169 ++++++++++++++++---------------- src/coreclr/src/inc/strongnameholders.h | 3 +- src/coreclr/src/vm/vmholder.h | 3 +- src/coreclr/src/vm/wrappers.h | 9 +- 7 files changed, 95 insertions(+), 102 deletions(-) diff --git a/src/coreclr/src/debug/di/process.cpp b/src/coreclr/src/debug/di/process.cpp index 4e6fe0b..f13e7b9 100644 --- a/src/coreclr/src/debug/di/process.cpp +++ b/src/coreclr/src/debug/di/process.cpp @@ -10990,8 +10990,7 @@ void CordbWin32EventThread::ThreadProc() } // Define a holder that calls code:DeleteIPCEventHelper -NEW_WRAPPER_TEMPLATE1(DeleteIPCEventHolderHelper, DeleteIPCEventHelper); -typedef DeleteIPCEventHolderHelper DeleteIPCEventHolder; +using DeleteIPCEventHolder = SpecializedWrapper; //--------------------------------------------------------------------------------------- // diff --git a/src/coreclr/src/inc/appxutil.h b/src/coreclr/src/inc/appxutil.h index c5fce69..644d3b9 100644 --- a/src/coreclr/src/inc/appxutil.h +++ b/src/coreclr/src/inc/appxutil.h @@ -14,8 +14,6 @@ //--------------------------------------------------------------------------------------------- // Forward declarations -template -class NewArrayHolder; BOOL WinRTSupported(); diff --git a/src/coreclr/src/inc/ex.h b/src/coreclr/src/inc/ex.h index 21ce9d3..48a3572 100644 --- a/src/coreclr/src/inc/ex.h +++ b/src/coreclr/src/inc/ex.h @@ -278,17 +278,13 @@ protected: }; #if 1 -template -inline void Exception__Delete(T* pvMemory); -template <> -inline void Exception__Delete(Exception* pvMemory) +inline void Exception__Delete(Exception* pvMemory) { Exception::Delete(pvMemory); } -NEW_WRAPPER_TEMPLATE1(ExceptionHolderTemplate, Exception__Delete<_TYPE>); -typedef ExceptionHolderTemplate ExceptionHolder; +using ExceptionHolder = SpecializedWrapper; #else //------------------------------------------------------------------------------ diff --git a/src/coreclr/src/inc/holder.h b/src/coreclr/src/inc/holder.h index c1f86b1..a5781d5 100644 --- a/src/coreclr/src/inc/holder.h +++ b/src/coreclr/src/inc/holder.h @@ -824,84 +824,68 @@ class Wrapper : public BaseWrapper, #define INDEBUG_AND_WINDOWS_FOR_HOLDERS(x) #endif -//--------------------------------------------------------------------------------------- -// -// New template wrapper type macros. These save some effort when specializing -// existing holder templates. (We would rather use a construct like: -// -// template -// typedef Holder<...> NewHolder; -// -// But this construct doesn't exist in C++. These macros ease some of the cruft necessary -// to get similar functionality out of class templates. -//----------------------------------------------------------------------------- +template +class SpecializedWrapper : public Wrapper<_TYPE*, DoNothing<_TYPE*>, _RELEASEF, NULL> +{ + using BaseT = Wrapper<_TYPE*, DoNothing<_TYPE*>, _RELEASEF, NULL>; +public: + FORCEINLINE SpecializedWrapper() : BaseT(NULL, FALSE) + { + STATIC_CONTRACT_WRAPPER; + INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;) + } + FORCEINLINE SpecializedWrapper(_TYPE* value) : BaseT(value) + { + STATIC_CONTRACT_WRAPPER; + INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;) + } + FORCEINLINE SpecializedWrapper(_TYPE* value, BOOL takeOwnership) : BaseT(value, takeOwnership) + { + STATIC_CONTRACT_WRAPPER; + INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;) + } + FORCEINLINE ~SpecializedWrapper() + { + } -// Dev10 VC++ has some of the new C++0x language extensions. Of particular interest here: -// rvalue references, which enables differentiation between named (lvalue) and -// temporary (rvalue) object references, enabling move semantics and perfect forwarding. -// See http://msdn.microsoft.com/en-us/library/dd293668.aspx for more information. - -// Enable copy construction and assignment from temporary objects. This permits Wrapper objects -// to be returned from methods, and for move assignment. -#define NEW_WRAPPER_TEMPLATE_RVALREF_METHODS(_NAME) \ - public: \ - FORCEINLINE _NAME(_NAME && other) \ - : BaseT(NULL, FALSE) \ - { \ - STATIC_CONTRACT_WRAPPER; \ - INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;) \ - *this = std::move(other); \ - } \ - FORCEINLINE _NAME& operator=(_NAME && other) \ - { \ - std::swap(BaseT::m_value, other.BaseT::m_value); \ - std::swap(BaseT::m_acquired, other.BaseT::m_acquired); \ - return *this; \ - } + SpecializedWrapper(SpecializedWrapper const &) = delete; + SpecializedWrapper & operator=(SpecializedWrapper const &) = delete; -#define NEW_WRAPPER_TEMPLATE1(_NAME, _RELEASEF) \ - template \ - class _NAME : public Wrapper<_TYPE*, DoNothing<_TYPE*>, _RELEASEF, NULL> \ - { \ - typedef Wrapper<_TYPE*, DoNothing<_TYPE*>, _RELEASEF, NULL> BaseT; \ - public: \ - FORCEINLINE _NAME() : BaseT(NULL, FALSE) \ - { \ - STATIC_CONTRACT_WRAPPER; \ - INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;) \ - } \ - FORCEINLINE _NAME(_TYPE* value) : BaseT(value) \ - { \ - STATIC_CONTRACT_WRAPPER; \ - INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;) \ - } \ - FORCEINLINE _NAME(_TYPE* value, BOOL takeOwnership) : BaseT(value, takeOwnership) \ - { \ - STATIC_CONTRACT_WRAPPER; \ - INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;) \ - } \ - FORCEINLINE ~_NAME() \ - { \ - } \ - FORCEINLINE _NAME& operator=(_TYPE * value) \ - { \ - STATIC_CONTRACT_WRAPPER; \ - BaseT::operator=(value); \ - return *this; \ - } \ - /* Since operator& is overloaded we need a way to get a type safe this pointer. */ \ - FORCEINLINE _NAME* GetAddr() \ - { \ - STATIC_CONTRACT_LEAF; \ - return this; \ - } \ - NEW_WRAPPER_TEMPLATE_RVALREF_METHODS(_NAME) \ - HIDE_GENERATED_METHODS(_NAME) \ - private: \ - /* m_ppValue: Do not use from source code: Only for convenient use from debugger */ \ - /* watch windows - saves five mouseclicks when inspecting holders. */ \ - INDEBUG_AND_WINDOWS_FOR_HOLDERS(_TYPE ** m_pvalue;) \ - }; + FORCEINLINE SpecializedWrapper& operator=(_TYPE * value) + { + STATIC_CONTRACT_WRAPPER; + BaseT::operator=(value); + return *this; + } + + FORCEINLINE SpecializedWrapper(SpecializedWrapper && other) + : BaseT(NULL, FALSE) + { + STATIC_CONTRACT_WRAPPER; + INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;) + *this = std::move(other); + } + + FORCEINLINE SpecializedWrapper& operator=(SpecializedWrapper && other) + { + BaseT::m_value = std::move(other.BaseT::m_value); + BaseT::m_acquired = std::move(other.BaseT::m_acquired); + other.BaseT::m_value = nullptr; + other.BaseT::m_acquired = FALSE; + return *this; + } + + /* Since operator& is overloaded we need a way to get a type safe this pointer. */ + FORCEINLINE SpecializedWrapper* GetAddr() + { + STATIC_CONTRACT_LEAF; + return this; + } + private: + /* m_ppValue: Do not use from source code: Only for convenient use from debugger */ + /* watch windows - saves five mouseclicks when inspecting holders. */ + INDEBUG_AND_WINDOWS_FOR_HOLDERS(_TYPE ** m_pvalue;) +}; //----------------------------------------------------------------------------- // NOTE: THIS IS UNSAFE TO USE IN THE VM for interop COM objects!! @@ -930,11 +914,14 @@ FORCEINLINE void DoTheRelease(TYPE *value) } } -NEW_WRAPPER_TEMPLATE1(DoNothingHolder, DoNothing<_TYPE*>); +template +using DoNothingHolder = SpecializedWrapper<_TYPE, DoNothing<_TYPE*>>; -NEW_WRAPPER_TEMPLATE1(ReleaseHolder, DoTheRelease<_TYPE>); +template +using ReleaseHolder = SpecializedWrapper<_TYPE, DoTheRelease<_TYPE>>; -NEW_WRAPPER_TEMPLATE1(NonVMComHolder, DoTheRelease<_TYPE>); +template +using NonVMComHolder = SpecializedWrapper<_TYPE, DoTheRelease<_TYPE>>; //----------------------------------------------------------------------------- @@ -957,7 +944,8 @@ FORCEINLINE void StubRelease(TYPE* value) value->DecRef(); } -NEW_WRAPPER_TEMPLATE1(StubHolder, StubRelease<_TYPE>); +template +using StubHolder = SpecializedWrapper<_TYPE, StubRelease<_TYPE>>; //----------------------------------------------------------------------------- // CoTaskMemHolder : CoTaskMemAlloc allocated memory holder @@ -974,7 +962,8 @@ FORCEINLINE void DeleteCoTaskMem(TYPE *value) CoTaskMemFree(value); } -NEW_WRAPPER_TEMPLATE1(CoTaskMemHolder, DeleteCoTaskMem<_TYPE>); +template +using CoTaskMemHolder = SpecializedWrapper<_TYPE, DeleteCoTaskMem<_TYPE>>; //----------------------------------------------------------------------------- // NewHolder : New'ed memory holder @@ -997,7 +986,8 @@ FORCEINLINE void Delete(TYPE *value) delete value; } -NEW_WRAPPER_TEMPLATE1(NewHolder, Delete<_TYPE>); +template +using NewHolder = SpecializedWrapper<_TYPE, Delete<_TYPE>>; //----------------------------------------------------------------------------- // NewExecutableHolder : New'ed memory holder for executable memory. @@ -1009,7 +999,8 @@ NEW_WRAPPER_TEMPLATE1(NewHolder, Delete<_TYPE>); // IJW template void DeleteExecutable(T *p); -NEW_WRAPPER_TEMPLATE1(NewExecutableHolder, DeleteExecutable<_TYPE>); +template +using NewExecutableHolder = SpecializedWrapper<_TYPE, DeleteExecutable<_TYPE>>; //----------------------------------------------------------------------------- // NewArrayHolder : New []'ed pointer holder @@ -1026,7 +1017,8 @@ FORCEINLINE void DeleteArray(TYPE *value) value = NULL; } -NEW_WRAPPER_TEMPLATE1(NewArrayHolder, DeleteArray<_TYPE>); +template +using NewArrayHolder = SpecializedWrapper<_TYPE, DeleteArray<_TYPE>>; typedef NewArrayHolder AStringHolder; typedef NewArrayHolder WStringHolder; @@ -1113,8 +1105,10 @@ namespace detail } #undef VISIBLE -NEW_WRAPPER_TEMPLATE1(ResetPointerHolder, detail::ZeroMem<_TYPE>::Invoke); -NEW_WRAPPER_TEMPLATE1(FieldNuller, detail::ZeroMem<_TYPE>::Invoke); +template +using ResetPointerHolder = SpecializedWrapper<_TYPE, detail::ZeroMem<_TYPE>::Invoke>; +template +using FieldNuller = SpecializedWrapper<_TYPE, detail::ZeroMem<_TYPE>::Invoke>; //----------------------------------------------------------------------------- // Wrap win32 functions using HANDLE @@ -1157,7 +1151,8 @@ typedef Wrapper, HolderFreeLibrary, NULL> HModuleHol template FORCEINLINE void DoLocalFree(T* pMem) { (LocalFree)((HLOCAL)pMem); } -NEW_WRAPPER_TEMPLATE1(LocalAllocHolder, DoLocalFree<_TYPE>); +template +using LocalAllocHolder = SpecializedWrapper<_TYPE, DoLocalFree<_TYPE>>; inline void BoolSet( _Out_ bool * val ) { *val = true; } inline void BoolUnset( _Out_ bool * val ) { *val = false; } diff --git a/src/coreclr/src/inc/strongnameholders.h b/src/coreclr/src/inc/strongnameholders.h index ecec994..d684e9d 100644 --- a/src/coreclr/src/inc/strongnameholders.h +++ b/src/coreclr/src/inc/strongnameholders.h @@ -18,6 +18,7 @@ void VoidStrongNameFreeBuffer(__in T *pBuffer) { StrongNameFreeBuffer(reinterpret_cast(pBuffer)); } -NEW_WRAPPER_TEMPLATE1(StrongNameBufferHolder, VoidStrongNameFreeBuffer<_TYPE>); +template +using StrongNameBufferHolder = SpecializedWrapper<_TYPE, VoidStrongNameFreeBuffer<_TYPE>>; #endif // !__STRONGNAME_HOLDERS_H__ diff --git a/src/coreclr/src/vm/vmholder.h b/src/coreclr/src/vm/vmholder.h index 9c265a1..003892b 100644 --- a/src/coreclr/src/vm/vmholder.h +++ b/src/coreclr/src/vm/vmholder.h @@ -18,6 +18,7 @@ inline void DoTheReleaseHost(TYPE *value) } } -NEW_WRAPPER_TEMPLATE1(HostComHolder, DoTheReleaseHost<_TYPE>); +template +using HostComHolder = SpecializedWrapper<_TYPE, DoTheReleaseHost<_TYPE>>; #endif diff --git a/src/coreclr/src/vm/wrappers.h b/src/coreclr/src/vm/wrappers.h index b9e40e8..a256cb5 100644 --- a/src/coreclr/src/vm/wrappers.h +++ b/src/coreclr/src/vm/wrappers.h @@ -109,11 +109,13 @@ inline void SafeComReleasePreemp(TYPE *value) SafeReleasePreemp((IUnknown*)value); } -NEW_WRAPPER_TEMPLATE1(SafeComHolder, SafeComRelease<_TYPE>); +template +using SafeComHolder = SpecializedWrapper<_TYPE, SafeComRelease<_TYPE>>; // Use this holder if you're already in preemptive mode for other reasons, // use SafeComHolder otherwise. -NEW_WRAPPER_TEMPLATE1(SafeComHolderPreemp, SafeComReleasePreemp<_TYPE>); +template +using SafeComHolderPreemp = SpecializedWrapper<_TYPE, SafeComReleasePreemp<_TYPE>>; @@ -166,7 +168,8 @@ void DeletePreemp(TYPE *value) delete value; } -NEW_WRAPPER_TEMPLATE1(NewPreempHolder, DeletePreemp<_TYPE>); +template +using NewPreempHolder = SpecializedWrapper<_TYPE, DeletePreemp<_TYPE>>; //----------------------------------------------------------------------------- -- 2.7.4