blob: df60ff951ecc82c5a7c20b38167179d6964df208 (
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
|
// 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.
//
// 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());
InterfaceInfo_t * pOldIMap = (InterfaceInfo_t *)pOldMT->GetInterfaceMap();
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.
OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOAD_APPROXPARENTS);
MethodTable *pItfMT = pOldIMap[iItf].GetApproxMethodTable(pOldMT->GetLoaderModule());
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
|