diff options
author | dotnet-bot <dotnet-bot@microsoft.com> | 2015-01-30 14:14:42 -0800 |
---|---|---|
committer | dotnet-bot <dotnet-bot@microsoft.com> | 2015-01-30 14:14:42 -0800 |
commit | ef1e2ab328087c61a6878c1e84f4fc5d710aebce (patch) | |
tree | dee1bbb89e9d722e16b0d1485e3cdd1b6c8e2cfa /src/vm/generics.inl | |
download | coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.tar.gz coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.tar.bz2 coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.zip |
Initial commit to populate CoreCLR repo
[tfs-changeset: 1407945]
Diffstat (limited to 'src/vm/generics.inl')
-rw-r--r-- | src/vm/generics.inl | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/src/vm/generics.inl b/src/vm/generics.inl new file mode 100644 index 0000000000..a7e93ab5ea --- /dev/null +++ b/src/vm/generics.inl @@ -0,0 +1,107 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// +// +// File: generics.inl +// + +// +// Helper functions for generics implementation +// + +// +// ============================================================================ + +#ifndef GENERICS_INL +#define GENERICS_INL + +#ifdef FEATURE_COMINTEROP +#include "winrttypenameconverter.h" +#endif + +// Generics helper functions +namespace Generics +{ +#ifndef DACCESS_COMPILE + inline void DetermineCCWTemplateAndGUIDPresenceOnNonCanonicalMethodTable( + // Input + MethodTable *pOldMT, BOOL fNewMTContainsGenericVariables, + // Output + BOOL *pfHasGuidInfo, BOOL *pfHasCCWTemplate) + { + STANDARD_VM_CONTRACT; + +#ifdef FEATURE_COMINTEROP + WORD wNumInterfaces = static_cast<WORD>(pOldMT->GetNumInterfaces()); + +#ifdef CLR_STANDALONE_BINDER + InterfaceInfo_t * pOldIMap = BinderMethodTable::GetInterfaceMap(pOldMT); +#else // !CLR_STANDALONE_BINDER + InterfaceInfo_t * pOldIMap = (InterfaceInfo_t *)pOldMT->GetInterfaceMap(); +#endif // !CLR_STANDALONE_BINDER + + BOOL fHasGuidInfo = FALSE; + + // Generic WinRT delegates expose a class interface and need the CCW template + BOOL fHasCCWTemplate = FALSE; + + if (!fNewMTContainsGenericVariables) + { + if (pOldMT->IsInterface()) + { + fHasGuidInfo = (pOldMT->IsProjectedFromWinRT() || WinRTTypeNameConverter::IsRedirectedType(pOldMT, WinMDAdapter::WinMDTypeKind_PInterface)); + } + else if (pOldMT->IsDelegate()) + { + fHasGuidInfo = (pOldMT->IsProjectedFromWinRT() || WinRTTypeNameConverter::IsRedirectedType(pOldMT, WinMDAdapter::WinMDTypeKind_PDelegate)); + + // Generic WinRT delegates expose a class interface and need a CCW template + fHasCCWTemplate = fHasGuidInfo; + } + + if (!fHasCCWTemplate) + { + if (pOldMT->IsInterface()) + { + // Interfaces need the CCW template if they are redirected and need variance + if (pOldMT->HasVariance() && + (pOldMT->IsProjectedFromWinRT() || WinRTTypeNameConverter::IsRedirectedType(pOldMT, WinMDAdapter::WinMDTypeKind_PInterface))) + { + fHasCCWTemplate = TRUE; + } + } + else + { + // Other types may need the CCW template if they implement generic interfaces + for (WORD iItf = 0; iItf < wNumInterfaces; iItf++) + { + // If the class implements a generic WinRT interface, it needs its own (per-instantiation) + // CCW template as the one on EEClass would be shared and hence useless. +#ifdef CLR_STANDALONE_BINDER + MethodTable *pItfMT = pOldIMap[iItf].m_pMethodTable.GetValue(); +#else // !CLR_STANDALONE_BINDER + OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOAD_APPROXPARENTS); + MethodTable *pItfMT = pOldIMap[iItf].GetApproxMethodTable(pOldMT->GetLoaderModule()); +#endif // !CLR_STANDALONE_BINDER + if (pItfMT->HasInstantiation() && + (pItfMT->IsProjectedFromWinRT() || WinRTTypeNameConverter::IsRedirectedType(pItfMT, WinMDAdapter::WinMDTypeKind_PInterface))) + { + fHasCCWTemplate = TRUE; + break; + } + } + } + } + } +#else // FEATURE_COMINTEROP + BOOL fHasGuidInfo = FALSE; + BOOL fHasCCWTemplate = FALSE; +#endif // FEATURE_COMINTEROP + *pfHasGuidInfo = fHasGuidInfo; + *pfHasCCWTemplate = fHasCCWTemplate; + } +#endif // DACCESS_COMPILE +} + +#endif // GENERICS_INL |