blob: a7e93ab5ea19df4f64672eaeda9034913760c38c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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
|