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: memberload.h
6//
7
8
9//
10
11//
12// ============================================================================
13
14#ifndef _MEMBERLOAD_H
15#define _MEMBERLOAD_H
16
17
18/*
19 * Include Files
20 */
21#include "eecontract.h"
22#include "argslot.h"
23#include "vars.hpp"
24#include "cor.h"
25#include "clrex.h"
26#include "hash.h"
27#include "crst.h"
28#include "declsec.h"
29#include "slist.h"
30#include "typehandle.h"
31#include "methodtable.h"
32#include "typectxt.h"
33
34//
35// This enum represents the property methods that can be passed to FindPropertyMethod().
36//
37
38enum EnumPropertyMethods
39{
40 PropertyGet = 0,
41 PropertySet = 1,
42};
43
44
45//
46// This enum represents the event methods that can be passed to FindEventMethod().
47//
48
49enum EnumEventMethods
50{
51 EventAdd = 0,
52 EventRemove = 1,
53 EventRaise = 2,
54};
55
56// The MemberLoader logic is analogous to the ClassLoader logic, i.e. it turn
57// tokens into internal EE descriptors.
58//
59// The implementations of these functions currently lies in class.cpp.
60class MemberLoader
61{
62
63
64public:
65 static void DECLSPEC_NORETURN ThrowMissingMethodException(MethodTable* pMT,
66 LPCSTR szMember,
67 Module *pModule,
68 PCCOR_SIGNATURE pSig,
69 DWORD cSig,
70 const SigTypeContext *pTypeContext);
71
72 static void DECLSPEC_NORETURN ThrowMissingFieldException( MethodTable *pMT,
73 LPCSTR szMember);
74
75 static MethodDesc* GetMethodDescFromMemberDefOrRefOrSpec(Module *pModule,
76 mdToken MemberRefOrDefOrSpec,
77 const SigTypeContext *pTypeContext, // Context for type parameters in any parent TypeSpec and in the instantiation in a MethodSpec
78 BOOL strictMetadataChecks, // Normally true - the zapper is one exception. Throw an exception if no generic method args given for a generic method, otherwise return the 'generic' instantiation
79 BOOL allowInstParam);
80
81 static FieldDesc* GetFieldDescFromMemberDefOrRef(Module *pModule,
82 mdMemberRef MemberDefOrRef,
83 const SigTypeContext *pTypeContext,
84 BOOL strictMetadataChecks);
85
86 static MethodDesc *GetMethodDescFromMethodDef(Module *pModule,
87 mdMethodDef MethodDef, // MethodDef token
88 Instantiation classInst, // Generic arguments for declaring class
89 Instantiation methodInst, // Generic arguments for declaring method
90 BOOL forceRemotable = FALSE); // force remotable MethodDesc
91 //
92 // Methods that actually do the work
93 //
94
95 static MethodDesc* GetMethodDescFromMethodDef(Module *pModule,
96 mdToken MethodDef,
97 BOOL strictMetadataChecks);
98
99 static FieldDesc* GetFieldDescFromFieldDef(Module *pModule,
100 mdToken FieldDef,
101 BOOL strictMetadataChecks);
102
103 static void GetDescFromMemberRef(Module * pModule,
104 mdToken MemberRef,
105 MethodDesc ** ppMD,
106 FieldDesc ** ppFD,
107 const SigTypeContext *pTypeContext,
108 BOOL strictMetadataChecks,
109 TypeHandle *ppTH,
110 // Because of inheritance, the actual type stored in metadata may be sub-class of the
111 // class that defines the member. The semantics (verification, security checks, etc.) is based on
112 // the actual type in metadata. This JIT-EE interface passes in TRUE here to get the actual type.
113 // If actualTypeRequired is false, returned *ppTH will be the MethodDesc::GetMethodTable/FieldDesc::GetEnclosingMethodTable
114 // except when generics are involved. The actual type will be still returned for generics since it is required
115 // for instantiation.
116 // If actualTypeRequired is true, returned *ppTH will always be the actual type defined in metadata.
117 BOOL actualTypeRequired = FALSE,
118 PCCOR_SIGNATURE * ppTypeSig = NULL, // Optionally, return generic signatures fetched from metadata during loading.
119 ULONG * pcbTypeSig = NULL);
120
121 static MethodDesc * GetMethodDescFromMemberRefAndType(Module * pModule,
122 mdToken MemberRef,
123 MethodTable * pMT);
124
125 static FieldDesc * GetFieldDescFromMemberRefAndType(Module * pModule,
126 mdToken MemberRef,
127 MethodTable * pMT);
128
129 static MethodDesc * GetMethodDescFromMethodSpec(Module * pModule,
130 mdToken MethodSpec,
131 const SigTypeContext *pTypeContext,
132 BOOL strictMetadataChecks,
133 BOOL allowInstParam,
134 TypeHandle *ppTH,
135 BOOL actualTypeRequired = FALSE, // See comment for GetDescFromMemberRef
136 PCCOR_SIGNATURE * ppTypeSig = NULL, // Optionally, return generic signatures fetched from metadata during loading.
137 ULONG * pcbTypeSig = NULL,
138 PCCOR_SIGNATURE * ppMethodSig = NULL,
139 ULONG * pcbMethodSig = NULL);
140
141 //-------------------------------------------------------------------
142 // METHOD AND FIELD LOOKUP BY NAME AND SIGNATURE
143 //
144
145 // Used by FindMethod and varieties
146 enum FM_Flags
147 {
148 // Default behaviour is to scan all methods, virtual and non-virtual, of the current type
149 // and all non-virtual methods of all parent types.
150
151 // Default set of flags - this must always be zero.
152 FM_Default = 0x0000,
153
154 // Case sensitivity
155 FM_IgnoreCase = 0x0001, // Name matching is case insensitive
156 FM_IgnoreName = (FM_IgnoreCase << 1), // Ignore the name altogether
157
158 // USE THE FOLLOWING WITH EXTREME CAUTION. We do not want to inadvertently
159 // change binding semantics by using this without a really good reason.
160
161 // Virtuals
162 FM_ExcludeNonVirtual = (FM_IgnoreName << 1), // has mdVirtual set
163 FM_ExcludeVirtual = (FM_ExcludeNonVirtual << 1), // does not have mdVirtual set.
164
165 // Accessibility.
166 // NOTE: These appear in the exact same order as mdPrivateScope ... mdPublic in corhdr.h. This enables some
167 // bit masking to quickly determine if a method qualifies in FM_ShouldSkipMethod.
168 FM_ExcludePrivateScope = (FM_ExcludeVirtual << 1), // Member not referenceable.
169 FM_ExcludePrivate = (FM_ExcludePrivateScope << 1), // Accessible only by the parent type.
170 FM_ExcludeFamANDAssem = (FM_ExcludePrivate << 1), // Accessible by sub-types only in this Assembly.
171 FM_ExcludeAssem = (FM_ExcludeFamANDAssem << 1), // Accessibly by anyone in the Assembly.
172 FM_ExcludeFamily = (FM_ExcludeAssem << 1), // Accessible only by type and sub-types.
173 FM_ExcludeFamORAssem = (FM_ExcludeFamily << 1), // Accessibly by sub-types anywhere, plus anyone in assembly.
174 FM_ExcludePublic = (FM_ExcludeFamORAssem << 1), // Accessibly by anyone who has visibility to this scope.
175 FM_Unique = (FM_ExcludePublic << 1), // Make sure the method is unique for the class
176
177 // This means that FindMethod will only consider mdPublic mdVirtual methods.
178 // This is the only time when name/sig lookup will look past the first match.
179 FM_ForInterface = (FM_ExcludeNonVirtual |
180 FM_ExcludePrivateScope |
181 FM_ExcludePrivate |
182 FM_ExcludeFamANDAssem |
183 FM_ExcludeAssem |
184 FM_ExcludeFamily |
185 FM_ExcludeFamORAssem),
186 };
187
188private:
189 // A mask to indicate that some filtering needs to be done.
190 static const FM_Flags FM_SpecialAccessMask = (FM_Flags) (FM_ExcludePrivateScope |
191 FM_ExcludePrivate |
192 FM_ExcludeFamANDAssem |
193 FM_ExcludeAssem |
194 FM_ExcludeFamily |
195 FM_ExcludeFamORAssem |
196 FM_ExcludePublic);
197
198 static const FM_Flags FM_SpecialVirtualMask = (FM_Flags) (FM_ExcludeNonVirtual |
199 FM_ExcludeVirtual);
200
201 // Typedef for string comparition functions.
202 typedef int (__cdecl *UTF8StringCompareFuncPtr)(const char *, const char *);
203
204 static inline UTF8StringCompareFuncPtr FM_GetStrCompFunc(DWORD dwFlags)
205 { LIMITED_METHOD_CONTRACT; return (dwFlags & FM_IgnoreCase) ? stricmpUTF8 : strcmp; }
206
207 static BOOL FM_PossibleToSkipMethod(FM_Flags flags);
208 static BOOL FM_ShouldSkipMethod(DWORD dwAttrs, FM_Flags flags);
209
210public:
211 static MethodDesc *FindMethod(
212 MethodTable * pMT,
213 LPCUTF8 pwzName,
214 LPHARDCODEDMETASIG pwzSignature,
215 FM_Flags flags = FM_Default);
216
217 // typeHnd is the type handle associated with the class being looked up.
218 // It has additional information in the case of a domain neutral class (Arrays)
219 static MethodDesc *FindMethod(
220 MethodTable * pMT,
221 LPCUTF8 pszName,
222 PCCOR_SIGNATURE pSignature,
223 DWORD cSignature,
224 Module* pModule,
225 FM_Flags flags = FM_Default,
226 const Substitution *pDefSubst = NULL);
227
228 static MethodDesc *FindMethod(MethodTable * pMT, mdMethodDef mb);
229
230 static MethodDesc *FindMethodByName(
231 MethodTable * pMT,
232 LPCUTF8 pszName,
233 FM_Flags flags = FM_Default);
234
235 static MethodDesc *FindPropertyMethod(
236 MethodTable * pMT,
237 LPCUTF8 pszName,
238 EnumPropertyMethods Method,
239 FM_Flags flags = FM_Default);
240
241 static MethodDesc *FindEventMethod(
242 MethodTable * pMT,
243 LPCUTF8 pszName,
244 EnumEventMethods Method,
245 FM_Flags flags = FM_Default);
246
247 static MethodDesc *FindMethodForInterfaceSlot(
248 MethodTable * pMT,
249 MethodTable *pInterface,
250 WORD slotNum);
251
252 // pSignature can be NULL to find any field with the given name
253 static FieldDesc *FindField(
254 MethodTable * pMT,
255 LPCUTF8 pszName,
256 PCCOR_SIGNATURE pSignature,
257 DWORD cSignature,
258 Module* pModule,
259 BOOL bCaseSensitive = TRUE);
260
261 static MethodDesc *FindConstructor(MethodTable * pMT, LPHARDCODEDMETASIG pwzSignature);
262 static MethodDesc *FindConstructor(MethodTable * pMT, PCCOR_SIGNATURE pSignature,DWORD cSignature, Module* pModule);
263};
264
265#endif // MEMBERLOAD_H
266