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.
5 // File: METHODTABLEBUILDER.INL
12 // ============================================================================
14 #ifndef _METHODTABLEBUILDER_INL_
15 #define _METHODTABLEBUILDER_INL_
17 //***************************************************************************************
18 inline MethodTableBuilder::DeclaredMethodIterator::DeclaredMethodIterator(
19 MethodTableBuilder &mtb) : m_mtb(mtb), m_idx(-1)
21 LIMITED_METHOD_CONTRACT;
24 //***************************************************************************************
25 inline int MethodTableBuilder::DeclaredMethodIterator::CurrentIndex()
27 LIMITED_METHOD_CONTRACT;
28 CONSISTENCY_CHECK_MSG(0 <= m_idx && m_idx < (int)m_mtb.NumDeclaredMethods(),
29 "Invalid iterator state.");
33 //***************************************************************************************
34 inline BOOL MethodTableBuilder::DeclaredMethodIterator::Next()
36 LIMITED_METHOD_CONTRACT;
37 if (m_idx + 1 >= (int)m_mtb.NumDeclaredMethods())
40 INDEBUG(m_debug_pMethod = GetMDMethod();)
44 //***************************************************************************************
45 inline BOOL MethodTableBuilder::DeclaredMethodIterator::Prev()
47 LIMITED_METHOD_CONTRACT;
51 INDEBUG(m_debug_pMethod = GetMDMethod();)
55 //***************************************************************************************
56 inline void MethodTableBuilder::DeclaredMethodIterator::ResetToEnd()
58 LIMITED_METHOD_CONTRACT;
59 m_idx = (int)m_mtb.NumDeclaredMethods();
62 //***************************************************************************************
63 inline mdMethodDef MethodTableBuilder::DeclaredMethodIterator::Token()
66 CONSISTENCY_CHECK(TypeFromToken(GetMDMethod()->GetMethodSignature().GetToken()) == mdtMethodDef);
67 return GetMDMethod()->GetMethodSignature().GetToken();
70 //***************************************************************************************
71 inline DWORD MethodTableBuilder::DeclaredMethodIterator::Attrs()
73 LIMITED_METHOD_CONTRACT;
74 return GetMDMethod()->GetDeclAttrs();
77 //***************************************************************************************
78 inline DWORD MethodTableBuilder::DeclaredMethodIterator::RVA()
80 LIMITED_METHOD_CONTRACT;
81 return GetMDMethod()->GetRVA();
84 //***************************************************************************************
85 inline DWORD MethodTableBuilder::DeclaredMethodIterator::ImplFlags()
87 LIMITED_METHOD_CONTRACT;
88 return GetMDMethod()->GetImplAttrs();
91 //***************************************************************************************
92 inline LPCSTR MethodTableBuilder::DeclaredMethodIterator::Name()
95 return GetMDMethod()->GetMethodSignature().GetName();
98 //***************************************************************************************
99 inline PCCOR_SIGNATURE MethodTableBuilder::DeclaredMethodIterator::GetSig(DWORD *pcbSig)
101 STANDARD_VM_CONTRACT;
102 *pcbSig = static_cast<DWORD>
103 (GetMDMethod()->GetMethodSignature().GetSignatureLength());
104 return GetMDMethod()->GetMethodSignature().GetSignature();
107 //***************************************************************************************
108 inline MethodTableBuilder::METHOD_IMPL_TYPE MethodTableBuilder::DeclaredMethodIterator::MethodImpl()
110 LIMITED_METHOD_CONTRACT;
111 return GetMDMethod()->GetMethodImplType();
114 //***************************************************************************************
115 inline BOOL MethodTableBuilder::DeclaredMethodIterator::IsMethodImpl()
117 LIMITED_METHOD_CONTRACT;
118 return MethodImpl() == METHOD_IMPL;
121 //***************************************************************************************
122 inline MethodTableBuilder::METHOD_TYPE MethodTableBuilder::DeclaredMethodIterator::MethodType()
124 LIMITED_METHOD_CONTRACT;
125 return GetMDMethod()->GetMethodType();
128 //***************************************************************************************
129 inline MethodTableBuilder::bmtMDMethod *
130 MethodTableBuilder::DeclaredMethodIterator::GetMDMethod()
132 LIMITED_METHOD_CONTRACT;
133 _ASSERTE(FitsIn<SLOT_INDEX>(m_idx)); // Review: m_idx should probably _be_ a SLOT_INDEX, but that asserts.
134 return (*m_mtb.bmtMethod)[static_cast<SLOT_INDEX>(m_idx)];
137 //*******************************************************************************
138 inline class MethodDesc *
139 MethodTableBuilder::DeclaredMethodIterator::GetIntroducingMethodDesc()
141 STANDARD_VM_CONTRACT;
143 bmtMDMethod *pCurrentMD = GetMDMethod();
144 DWORD dwSlot = pCurrentMD->GetSlotIndex();
145 MethodDesc *pIntroducingMD = NULL;
147 bmtRTType *pParentType = pCurrentMD->GetOwningType()->GetParentType();
148 bmtRTType *pPrevParentType = NULL;
150 // Find this method in the parent.
151 // If it does exist in the parent, it would be at the same vtable slot.
152 while (pParentType != NULL &&
153 dwSlot < pParentType->GetMethodTable()->GetNumVirtuals())
155 pPrevParentType = pParentType;
156 pParentType = pParentType->GetParentType();
159 if (pPrevParentType != NULL)
162 pPrevParentType->GetMethodTable()->GetMethodDescForSlot(dwSlot);
165 return pIntroducingMD;
169 //***************************************************************************************
170 inline MethodTableBuilder::bmtMDMethod *
171 MethodTableBuilder::DeclaredMethodIterator::operator->()
173 return GetMDMethod();
176 //***************************************************************************************
178 MethodTableBuilder::bmtMethodHandle::operator==(
179 const bmtMethodHandle &rhs) const
181 return m_handle == rhs.m_handle;
184 //***************************************************************************************
186 // The MethodNameHash is a temporary loader structure which may be allocated if there are a large number of
187 // methods in a class, to quickly get from a method name to a MethodDesc (potentially a chain of MethodDescs).
190 //***************************************************************************************
191 // Returns TRUE for success, FALSE for failure
192 template <typename Data>
194 FixedCapacityStackingAllocatedUTF8StringHash<Data>::Init(
196 StackingAllocator * pAllocator)
202 PRECONDITION(CheckPointer(this));
206 // Given dwMaxEntries, determine a good value for the number of hash buckets
207 m_dwNumBuckets = (dwMaxEntries / 10);
209 if (m_dwNumBuckets < 5)
212 S_UINT32 scbMemory = (S_UINT32(m_dwNumBuckets) * S_UINT32(sizeof(HashEntry*))) +
213 (S_UINT32(dwMaxEntries) * S_UINT32(sizeof(HashEntry)));
215 if(scbMemory.IsOverflow())
216 ThrowHR(E_INVALIDARG);
220 m_pMemoryStart = (BYTE*)pAllocator->Alloc(scbMemory);
223 { // We're given the number of hash table entries we're going to insert,
224 // so we can allocate the appropriate size
225 m_pMemoryStart = new BYTE[scbMemory.Value()];
228 INDEBUG(m_pDebugEndMemory = m_pMemoryStart + scbMemory.Value();)
231 m_pMemory = m_pMemoryStart;
233 // Allocate the buckets out of the alloc ptr
234 m_pBuckets = (HashEntry**) m_pMemory;
235 m_pMemory += sizeof(HashEntry*)*m_dwNumBuckets;
237 // Buckets all point to empty lists to begin with
238 memset(m_pBuckets, 0, scbMemory.Value());
241 //***************************************************************************************
242 // Insert new entry at head of list
243 template <typename Data>
245 FixedCapacityStackingAllocatedUTF8StringHash<Data>::Insert(
249 LIMITED_METHOD_CONTRACT;
250 DWORD dwHash = GetHashCode(pszName);
251 DWORD dwBucket = dwHash % m_dwNumBuckets;
252 HashEntry * pNewEntry;
254 pNewEntry = (HashEntry *) m_pMemory;
255 m_pMemory += sizeof(HashEntry);
257 _ASSERTE(m_pMemory <= m_pDebugEndMemory);
259 // Insert at head of bucket chain
260 pNewEntry->m_pNext = m_pBuckets[dwBucket];
261 pNewEntry->m_data = data;
262 pNewEntry->m_dwHashValue = dwHash;
263 pNewEntry->m_pKey = pszName;
265 m_pBuckets[dwBucket] = pNewEntry;
268 //***************************************************************************************
269 // Return the first HashEntry with this name, or NULL if there is no such entry
270 template <typename Data>
271 typename FixedCapacityStackingAllocatedUTF8StringHash<Data>::HashEntry *
272 FixedCapacityStackingAllocatedUTF8StringHash<Data>::Lookup(
275 STATIC_CONTRACT_NOTHROW;
276 STATIC_CONTRACT_GC_NOTRIGGER;
277 STATIC_CONTRACT_FORBID_FAULT;
279 DWORD dwHash = GetHashCode(pszName);
280 DWORD dwBucket = dwHash % m_dwNumBuckets;
283 for (pSearch = m_pBuckets[dwBucket]; pSearch; pSearch = pSearch->m_pNext)
285 if (pSearch->m_dwHashValue == dwHash && !strcmp(pSearch->m_pKey, pszName))
294 //***************************************************************************************
295 // Return the first HashEntry with this name, or NULL if there is no such entry
296 template <typename Data>
297 typename FixedCapacityStackingAllocatedUTF8StringHash<Data>::HashEntry *
298 FixedCapacityStackingAllocatedUTF8StringHash<Data>::FindNext(
301 STATIC_CONTRACT_NOTHROW;
302 STATIC_CONTRACT_GC_NOTRIGGER;
303 STATIC_CONTRACT_FORBID_FAULT;
304 CONSISTENCY_CHECK(CheckPointer(pEntry));
306 LPCUTF8 key = pEntry->m_pKey;
307 DWORD hash = pEntry->m_dwHashValue;
309 pEntry = pEntry->m_pNext;
310 while (pEntry != NULL)
312 if (pEntry->m_dwHashValue == hash &&
313 strcmp(pEntry->m_pKey, key) == 0)
317 pEntry = pEntry->m_pNext;
323 #endif // DACCESS_COMPILE
325 #ifndef DACCESS_COMPILE
327 //***************************************************************************************
328 #define CALL_TYPE_HANDLE_METHOD(m) \
329 ((IsRTType()) ? (AsRTType()->m()) : (AsMDType()->m()))
331 //***************************************************************************************
332 inline MethodTableBuilder::bmtTypeHandle
333 MethodTableBuilder::bmtTypeHandle::GetParentType() const
335 LIMITED_METHOD_CONTRACT;
336 return CALL_TYPE_HANDLE_METHOD(GetParentType);
339 //***************************************************************************************
341 MethodTableBuilder::bmtTypeHandle::IsNested() const
343 LIMITED_METHOD_CONTRACT;
344 return CALL_TYPE_HANDLE_METHOD(IsNested);
347 //***************************************************************************************
349 MethodTableBuilder::bmtTypeHandle::GetEnclosingTypeToken() const
351 LIMITED_METHOD_CONTRACT;
352 return CALL_TYPE_HANDLE_METHOD(GetEnclosingTypeToken);
355 //***************************************************************************************
357 MethodTableBuilder::bmtTypeHandle::GetModule() const
359 LIMITED_METHOD_CONTRACT;
360 return CALL_TYPE_HANDLE_METHOD(GetModule);
363 //***************************************************************************************
365 MethodTableBuilder::bmtTypeHandle::GetTypeDefToken() const
367 LIMITED_METHOD_CONTRACT;
368 return CALL_TYPE_HANDLE_METHOD(GetTypeDefToken);
371 //***************************************************************************************
372 inline const Substitution &
373 MethodTableBuilder::bmtTypeHandle::GetSubstitution() const
375 LIMITED_METHOD_CONTRACT;
376 return CALL_TYPE_HANDLE_METHOD(GetSubstitution);
379 //***************************************************************************************
381 MethodTableBuilder::bmtTypeHandle::GetMethodTable() const
383 LIMITED_METHOD_CONTRACT;
384 return CALL_TYPE_HANDLE_METHOD(GetMethodTable);
387 //***************************************************************************************
389 MethodTableBuilder::bmtTypeHandle::GetAttrs() const
391 LIMITED_METHOD_CONTRACT;
392 return CALL_TYPE_HANDLE_METHOD(GetAttrs);
395 //***************************************************************************************
397 MethodTableBuilder::bmtTypeHandle::IsInterface() const
399 LIMITED_METHOD_CONTRACT;
400 return CALL_TYPE_HANDLE_METHOD(IsInterface);
403 #undef CALL_TYPE_HANDLE_METHOD
405 //***************************************************************************************
406 #define CALL_METHOD_HANDLE_METHOD(m) \
407 ((IsRTMethod()) ? (AsRTMethod()->m()) : (AsMDMethod()->m()))
409 //***************************************************************************************
410 inline MethodTableBuilder::bmtTypeHandle
411 MethodTableBuilder::bmtMethodHandle::GetOwningType() const
413 LIMITED_METHOD_CONTRACT;
415 return bmtTypeHandle(AsRTMethod()->GetOwningType());
417 return bmtTypeHandle(AsMDMethod()->GetOwningType());
420 //***************************************************************************************
422 MethodTableBuilder::bmtMethodHandle::GetDeclAttrs() const
424 LIMITED_METHOD_CONTRACT;
425 return CALL_METHOD_HANDLE_METHOD(GetDeclAttrs);
428 //***************************************************************************************
430 MethodTableBuilder::bmtMethodHandle::GetImplAttrs() const
432 LIMITED_METHOD_CONTRACT;
433 return CALL_METHOD_HANDLE_METHOD(GetImplAttrs);
436 //***************************************************************************************
437 inline MethodTableBuilder::SLOT_INDEX
438 MethodTableBuilder::bmtMethodHandle::GetSlotIndex() const
440 LIMITED_METHOD_CONTRACT;
441 return CALL_METHOD_HANDLE_METHOD(GetSlotIndex);
444 //***************************************************************************************
445 inline const MethodTableBuilder::MethodSignature &
446 MethodTableBuilder::bmtMethodHandle::GetMethodSignature() const
448 LIMITED_METHOD_CONTRACT;
449 return CALL_METHOD_HANDLE_METHOD(GetMethodSignature);
452 //***************************************************************************************
454 MethodTableBuilder::bmtMethodHandle::GetMethodDesc() const
456 LIMITED_METHOD_CONTRACT;
457 return CALL_METHOD_HANDLE_METHOD(GetMethodDesc);
460 #undef CALL_METHOD_HANDLE_METHOD
462 //***************************************************************************************
464 MethodTableBuilder::bmtRTMethod::GetDeclAttrs() const
466 LIMITED_METHOD_CONTRACT;
467 return GetMethodDesc()->GetAttrs();
470 //***************************************************************************************
472 MethodTableBuilder::bmtRTMethod::GetImplAttrs() const
474 LIMITED_METHOD_CONTRACT;
475 return GetMethodDesc()->GetImplAttrs();
478 //***************************************************************************************
479 inline MethodTableBuilder::SLOT_INDEX
480 MethodTableBuilder::bmtRTMethod::GetSlotIndex() const
482 LIMITED_METHOD_CONTRACT;
483 return GetMethodDesc()->GetSlot();
486 //***************************************************************************************
488 MethodTableBuilder::bmtMDMethod::SetSlotIndex(SLOT_INDEX idx)
490 LIMITED_METHOD_CONTRACT;
491 CONSISTENCY_CHECK(m_pMD == NULL);
495 //***************************************************************************************
497 MethodTableBuilder::bmtMDMethod::SetUnboxedSlotIndex(SLOT_INDEX idx)
499 LIMITED_METHOD_CONTRACT;
500 CONSISTENCY_CHECK(m_pUnboxedMD == NULL);
501 m_unboxedSlotIndex = idx;
504 //***************************************************************************************
506 MethodTableBuilder::GetMethodClassification(MethodTableBuilder::METHOD_TYPE type)
508 LIMITED_METHOD_CONTRACT;
509 // Verify that the enums are in sync, so we can do the conversion by simple cast.
510 C_ASSERT((DWORD)METHOD_TYPE_NORMAL == (DWORD)mcIL);
511 C_ASSERT((DWORD)METHOD_TYPE_FCALL == (DWORD)mcFCall);
512 C_ASSERT((DWORD)METHOD_TYPE_NDIRECT == (DWORD)mcNDirect);
513 C_ASSERT((DWORD)METHOD_TYPE_EEIMPL == (DWORD)mcEEImpl);
514 C_ASSERT((DWORD)METHOD_TYPE_INSTANTIATED == (DWORD)mcInstantiated);
515 #ifdef FEATURE_COMINTEROP
516 C_ASSERT((DWORD)METHOD_TYPE_COMINTEROP == (DWORD)mcComInterop);
522 #endif // _METHODTABLEBUILDER_INL_