summaryrefslogtreecommitdiff
path: root/src/vm/wrappers.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/wrappers.h')
-rw-r--r--src/vm/wrappers.h350
1 files changed, 350 insertions, 0 deletions
diff --git a/src/vm/wrappers.h b/src/vm/wrappers.h
new file mode 100644
index 0000000000..5d51252e49
--- /dev/null
+++ b/src/vm/wrappers.h
@@ -0,0 +1,350 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+
+#ifndef _WRAPPERS_H_
+#define _WRAPPERS_H_
+
+#include "metadata.h"
+#include "interoputil.h"
+#ifdef FEATURE_COMINTEROP
+#include "windowsstring.h"
+#endif
+
+class MDEnumHolder
+{
+public:
+ inline MDEnumHolder(IMDInternalImport* IMDII)
+ {
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ PRECONDITION(CheckPointer(IMDII));
+ }
+ CONTRACTL_END;
+
+ m_IMDII = IMDII;
+
+ }
+
+ inline ~MDEnumHolder()
+ {
+ WRAPPER_NO_CONTRACT;
+ m_IMDII->EnumClose(&m_HEnum);
+ }
+
+ inline operator HENUMInternal()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_HEnum;
+ }
+
+ inline HENUMInternal* operator&()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return static_cast<HENUMInternal*>(&m_HEnum);
+ }
+
+private:
+ MDEnumHolder() {LIMITED_METHOD_CONTRACT;} // Must use parameterized constructor
+
+ HENUMInternal m_HEnum;
+ IMDInternalImport* m_IMDII;
+};
+
+
+//--------------------------------------------------------------------------------
+// safe variant helper
+void SafeVariantClear(_Inout_ VARIANT* pVar);
+
+class VariantHolder
+{
+public:
+ inline VariantHolder()
+ {
+ LIMITED_METHOD_CONTRACT;
+ memset(&m_var, 0, sizeof(VARIANT));
+ }
+
+ inline ~VariantHolder()
+ {
+ WRAPPER_NO_CONTRACT;
+ SafeVariantClear(&m_var);
+ }
+
+ inline VARIANT* operator&()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return static_cast<VARIANT*>(&m_var);
+ }
+
+private:
+ VARIANT m_var;
+};
+
+
+template <typename TYPE>
+inline void SafeComRelease(TYPE *value)
+{
+ CONTRACTL {
+ NOTHROW;
+ GC_TRIGGERS;
+ MODE_ANY;
+ SO_TOLERANT;
+ } CONTRACTL_END;
+
+ SafeRelease((IUnknown*)value);
+}
+template <typename TYPE>
+inline void SafeComReleasePreemp(TYPE *value)
+{
+ CONTRACTL {
+ NOTHROW;
+ GC_TRIGGERS;
+ MODE_PREEMPTIVE;
+ SO_TOLERANT;
+ } CONTRACTL_END;
+
+ SafeReleasePreemp((IUnknown*)value);
+}
+
+NEW_WRAPPER_TEMPLATE1(SafeComHolder, SafeComRelease<_TYPE>);
+
+// Use this holder if you're already in preemptive mode for other reasons,
+// use SafeComHolder otherwise.
+NEW_WRAPPER_TEMPLATE1(SafeComHolderPreemp, SafeComReleasePreemp<_TYPE>);
+
+
+
+#ifdef FEATURE_COMINTEROP
+#ifdef CROSSGEN_COMPILE
+ namespace clr
+ {
+ namespace winrt
+ {
+ template <typename ItfT> inline
+ HRESULT GetActivationFactory(
+ __in WinRtStringRef const & wzActivatableClassId,
+ __deref_out ItfT** ppItf)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return GetActivationFactory(wzActivatableClassId, ppItf);
+ }
+
+ template <typename ItfT> inline
+ HRESULT GetActivationFactory(
+ __in WinRtStringRef const & wzActivatableClassId,
+ __out typename SafeComHolderPreemp<ItfT>* pItf)
+ {
+ STATIC_CONTRACT_WRAPPER;
+
+ if (pItf == nullptr)
+ return E_INVALIDARG;
+
+ return GetActivationFactory(wzActivatableClassId, (ItfT**)&(*pItf));
+ }
+ }
+ }
+#endif //CROSSGEN_COMPILE
+#endif //FEATURE_COMINTEROP
+
+//-----------------------------------------------------------------------------
+// NewPreempHolder : New'ed memory holder, deletes in preemp mode.
+//
+// {
+// NewPreempHolder<Foo> foo = new Foo ();
+// } // delete foo on out of scope in preemp mode.
+//-----------------------------------------------------------------------------
+
+template <typename TYPE>
+void DeletePreemp(TYPE *value)
+{
+ WRAPPER_NO_CONTRACT;
+
+ GCX_PREEMP();
+ delete value;
+}
+
+NEW_WRAPPER_TEMPLATE1(NewPreempHolder, DeletePreemp<_TYPE>);
+
+
+//-----------------------------------------------------------------------------
+// VariantPtrHolder : Variant holder, Calls VariantClear on scope exit.
+//
+// {
+// VariantHolder foo = pVar
+// } // Call SafeVariantClear on out of scope.
+//-----------------------------------------------------------------------------
+
+FORCEINLINE void VariantPtrRelease(VARIANT* value)
+{
+ WRAPPER_NO_CONTRACT;
+
+ if (value)
+ {
+ SafeVariantClear(value);
+ }
+}
+
+class VariantPtrHolder : public Wrapper<VARIANT*, VariantPtrDoNothing, VariantPtrRelease, NULL>
+{
+public:
+ VariantPtrHolder(VARIANT* p = NULL)
+ : Wrapper<VARIANT*, VariantPtrDoNothing, VariantPtrRelease, NULL>(p)
+ {
+ LIMITED_METHOD_CONTRACT;
+ }
+
+ FORCEINLINE void operator=(VARIANT* p)
+ {
+ WRAPPER_NO_CONTRACT;
+
+ Wrapper<VARIANT*, VariantPtrDoNothing, VariantPtrRelease, NULL>::operator=(p);
+ }
+};
+
+//-----------------------------------------------------------------------------
+// SafeArrayPtrHolder : SafeArray holder, Calls SafeArrayDestroy on scope exit.
+// In cooperative mode this holder should be used instead of code:SafeArrayHolder.
+//
+// {
+// SafeArrayPtrHolder foo = pSafeArray
+// } // Call SafeArrayDestroy on out of scope.
+//-----------------------------------------------------------------------------
+
+FORCEINLINE void SafeArrayPtrRelease(SAFEARRAY* value)
+{
+ WRAPPER_NO_CONTRACT;
+
+ if (value)
+ {
+ // SafeArrayDestroy may block and may also call back to MODE_PREEMPTIVE
+ // runtime functions like e.g. code:Unknown_Release_Internal
+ GCX_PREEMP();
+
+ HRESULT hr; hr = SafeArrayDestroy(value);
+ _ASSERTE(SUCCEEDED(hr));
+ }
+}
+
+class SafeArrayPtrHolder : public Wrapper<SAFEARRAY*, SafeArrayDoNothing, SafeArrayPtrRelease, NULL>
+{
+public:
+ SafeArrayPtrHolder(SAFEARRAY* p = NULL)
+ : Wrapper<SAFEARRAY*, SafeArrayDoNothing, SafeArrayPtrRelease, NULL>(p)
+ {
+ LIMITED_METHOD_CONTRACT;
+ }
+
+ FORCEINLINE void operator=(SAFEARRAY* p)
+ {
+ WRAPPER_NO_CONTRACT;
+
+ Wrapper<SAFEARRAY*, SafeArrayDoNothing, SafeArrayPtrRelease, NULL>::operator=(p);
+ }
+};
+
+//-----------------------------------------------------------------------------
+// ZeroHolder : Sets value to zero on context exit.
+//
+// {
+// ZeroHolder foo = &data;
+// } // set data to zero on context exit
+//-----------------------------------------------------------------------------
+
+FORCEINLINE void ZeroRelease(VOID* value)
+{
+ LIMITED_METHOD_CONTRACT;
+ if (value)
+ {
+ (*(size_t*)value) = 0;
+ }
+}
+
+class ZeroHolder : public Wrapper<VOID*, ZeroDoNothing, ZeroRelease, NULL>
+{
+public:
+ ZeroHolder(VOID* p = NULL)
+ : Wrapper<VOID*, ZeroDoNothing, ZeroRelease, NULL>(p)
+ {
+ LIMITED_METHOD_CONTRACT;
+ }
+
+ FORCEINLINE void operator=(VOID* p)
+ {
+ WRAPPER_NO_CONTRACT;
+
+ Wrapper<VOID*, ZeroDoNothing, ZeroRelease, NULL>::operator=(p);
+ }
+};
+
+#ifdef FEATURE_COMINTEROP
+class TYPEATTRHolder
+{
+public:
+ TYPEATTRHolder(ITypeInfo* pTypeInfo)
+ {
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ PRECONDITION(CheckPointer(pTypeInfo, NULL_OK));
+ }
+ CONTRACTL_END;
+
+ m_pTypeInfo = pTypeInfo;
+ m_TYPEATTR = NULL;
+ }
+
+ ~TYPEATTRHolder()
+ {
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_TRIGGERS;
+ MODE_ANY;
+ PRECONDITION(m_TYPEATTR ? CheckPointer(m_pTypeInfo) : CheckPointer(m_pTypeInfo, NULL_OK));
+ }
+ CONTRACTL_END;
+
+ if (m_TYPEATTR)
+ {
+ GCX_PREEMP();
+ m_pTypeInfo->ReleaseTypeAttr(m_TYPEATTR);
+ }
+ }
+
+ inline void operator=(TYPEATTR* value)
+ {
+ LIMITED_METHOD_CONTRACT;
+ m_TYPEATTR = value;
+ }
+
+ inline TYPEATTR** operator&()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return &m_TYPEATTR;
+ }
+
+ inline TYPEATTR* operator->()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_TYPEATTR;
+ }
+
+private:
+ TYPEATTRHolder ()
+ {
+ LIMITED_METHOD_CONTRACT;
+ }
+
+ ITypeInfo* m_pTypeInfo;
+ TYPEATTR* m_TYPEATTR;
+};
+#endif // FEATURE_COMINTEROP
+
+#endif // _WRAPPERS_H_