Merge pull request #14619 from briansull/emitter-cleanup
[platform/upstream/coreclr.git] / src / vm / winrtredirector.h
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 //
5 // File: winrtredirector.h
6 //
7
8 //
9
10 //
11 // ============================================================================
12
13 #ifndef WINRT_DELEGATE_REDIRECTOR_H
14 #define WINRT_DELEGATE_REDIRECTOR_H
15
16 #include "winrttypenameconverter.h"
17
18 // Provides functionality related to redirecting WinRT interfaces.
19 // @TODO: This should take advantage of the macros in WinRTProjectedTypes.h instead of hardcoding
20 // the knowledge about redirected interfaces here.
21 class WinRTInterfaceRedirector
22 {
23 public:
24     // Returns a MethodDesc to be used as an interop stub for the given redirected interface/slot/direction.
25     static MethodDesc *GetStubMethodForRedirectedInterface(
26         WinMDAdapter::RedirectedTypeIndex   interfaceIndex,                // redirected interface index
27         int                                 slot,                          // slot number of the method for which a stub is needed
28         TypeHandle::InteropKind             interopKind,                   // Interop_ManagedToNative (stub for RCW) or Interop_NativeToManaged (stub for CCW)
29         BOOL                                fICollectionStub,              // need stub for ICollection`1 (only valid with Interop_ManagedToNative)
30         Instantiation                       methodInst = Instantiation()); // requested method instantiation if the stub method is generic
31
32     // Returns a MethodDesc to be used as an interop stub for the given method and direction.
33     static MethodDesc *GetStubMethodForRedirectedInterfaceMethod(MethodDesc *pMD, TypeHandle::InteropKind interopKind);
34
35     // Returns MethodTable (typical instantiation) of the Framework copy of the specified redirected WinRT interface.
36     static MethodTable *GetWinRTTypeForRedirectedInterfaceIndex(WinMDAdapter::RedirectedTypeIndex index);
37     
38     // Loads a method from the given Framework assembly.
39     static MethodDesc *LoadMethodFromRedirectedAssembly(LPCUTF8 szAssemblyQualifiedTypeName, LPCUTF8 szMethodName);
40
41     // Lists WinRT-legal types assignable from .NET reference types that are projected from WinRT structures/arrays/delegates.
42     enum WinRTLegalStructureBaseType
43     {
44         BaseType_None,
45         BaseType_Object,            // System.Object                                (assignable from Type, string, Exception)
46         BaseType_IEnumerable,       // System.Collections.IEnumerable               (assignable from string)
47         BaseType_IEnumerableOfChar  // System.Collections.Generic.IEnumerable<char> (assignable from string)
48     };
49
50     // Determines if the generic argument in the given instantiation is a WinRT-legal base type of a WinRT structure type.
51     static WinRTLegalStructureBaseType GetStructureBaseType(Instantiation inst)
52     {
53         LIMITED_METHOD_CONTRACT;
54
55         _ASSERTE(inst.GetNumArgs() == 1);
56
57         if (!inst[0].IsTypeDesc())
58         {
59             MethodTable *pInstArgMT = inst[0].AsMethodTable();
60             
61             if (pInstArgMT == g_pObjectClass)
62                 return BaseType_Object;
63
64             if (pInstArgMT == MscorlibBinder::GetExistingClass(CLASS__IENUMERABLE))
65                 return BaseType_IEnumerable;
66
67             if (pInstArgMT->HasSameTypeDefAs(MscorlibBinder::GetExistingClass(CLASS__IENUMERABLEGENERIC)) &&
68                 pInstArgMT->GetInstantiation()[0].GetSignatureCorElementType() == ELEMENT_TYPE_CHAR)
69                 return BaseType_IEnumerableOfChar;
70         }
71         return BaseType_None;
72     }
73
74     // Returns the redirection index if the MethodTable* is a redirected interface.
75     static inline bool ResolveRedirectedInterface(MethodTable *pMT, WinMDAdapter::RedirectedTypeIndex * pIndex);
76
77 #ifdef _DEBUG
78     static void VerifyRedirectedInterfaceStubs();
79 #endif // _DEBUG
80
81 private:
82     static inline int GetStubInfoIndex(WinMDAdapter::RedirectedTypeIndex index)
83     {
84         LIMITED_METHOD_CONTRACT;
85
86         switch (index)
87         {
88             case WinMDAdapter::RedirectedTypeIndex_System_Collections_Generic_IEnumerable:                  return 0;
89             case WinMDAdapter::RedirectedTypeIndex_System_Collections_Generic_IList:                        return 1;
90             case WinMDAdapter::RedirectedTypeIndex_System_Collections_Generic_IDictionary:                  return 2;
91             case WinMDAdapter::RedirectedTypeIndex_System_Collections_Generic_IReadOnlyList:                return 3;
92             case WinMDAdapter::RedirectedTypeIndex_System_Collections_Generic_IReadOnlyDictionary:          return 4;
93             case WinMDAdapter::RedirectedTypeIndex_System_Collections_IEnumerable:                          return 5;
94             case WinMDAdapter::RedirectedTypeIndex_System_Collections_IList:                                return 6;
95             case WinMDAdapter::RedirectedTypeIndex_System_Collections_Specialized_INotifyCollectionChanged: return 7;
96             case WinMDAdapter::RedirectedTypeIndex_System_ComponentModel_INotifyPropertyChanged:            return 8;
97             case WinMDAdapter::RedirectedTypeIndex_System_Windows_Input_ICommand:                           return 9;
98             case WinMDAdapter::RedirectedTypeIndex_System_IDisposable:                                      return 10;
99             default:
100                 UNREACHABLE();
101         }
102     }
103
104     struct RedirectedInterfaceStubInfo
105     {
106         const BinderClassID m_WinRTInterface;
107         const int m_iCLRMethodCount;
108         const BinderMethodID *m_rCLRStubMethods;
109         const int m_iWinRTMethodCount;
110         const BinderMethodID *m_rWinRTStubMethods;
111     };
112
113     struct NonMscorlibRedirectedInterfaceInfo
114     {
115         const LPCUTF8 m_szWinRTInterfaceAssemblyQualifiedTypeName;
116         const LPCUTF8 m_szCLRStubClassAssemblyQualifiedTypeName;
117         const LPCUTF8 m_szWinRTStubClassAssemblyQualifiedTypeName;
118         const LPCUTF8 *m_rszMethodNames;
119     };
120
121     enum
122     {
123         s_NumRedirectedInterfaces = 11
124     };
125
126     // Describes stubs used for marshaling of redirected interfaces.
127     const static RedirectedInterfaceStubInfo s_rInterfaceStubInfos[2 * s_NumRedirectedInterfaces];
128     const static NonMscorlibRedirectedInterfaceInfo s_rNonMscorlibInterfaceInfos[3];
129
130     const static int NON_MSCORLIB_MARKER = 0x80000000;
131 };
132
133
134 // Provides functionality related to redirecting WinRT delegates.
135 class WinRTDelegateRedirector
136 {
137 public:
138     static MethodTable *GetWinRTTypeForRedirectedDelegateIndex(WinMDAdapter::RedirectedTypeIndex index);
139
140     static bool ResolveRedirectedDelegate(MethodTable *pMT, WinMDAdapter::RedirectedTypeIndex *pIndex);
141 };
142
143 #endif // WINRT_DELEGATE_REDIRECTOR_H