diff options
Diffstat (limited to 'src/vm/typehandle.inl')
-rw-r--r-- | src/vm/typehandle.inl | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/src/vm/typehandle.inl b/src/vm/typehandle.inl new file mode 100644 index 0000000000..9f6fb7b344 --- /dev/null +++ b/src/vm/typehandle.inl @@ -0,0 +1,285 @@ +// 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: typehandle.inl +// + + +// + +// +// ============================================================================ + + +#ifndef _TYPEHANDLE_INL_ +#define _TYPEHANDLE_INL_ + +#include "typehandle.h" + +inline mdTypeDef TypeHandle::GetCl() const +{ + LIMITED_METHOD_DAC_CONTRACT; + + PREFIX_ASSUME(GetMethodTable() != NULL); + return GetMethodTable()->GetCl(); +} + +inline PTR_MethodTable TypeHandle::GetMethodTable() const +{ + LIMITED_METHOD_DAC_CONTRACT; + + if (IsTypeDesc()) + return(AsTypeDesc()->GetMethodTable()); + else + return AsMethodTable(); +} + +inline void TypeHandle::SetIsFullyLoaded() +{ + LIMITED_METHOD_CONTRACT; + + if (IsTypeDesc()) + return AsTypeDesc()->SetIsFullyLoaded(); + else + return AsMethodTable()->SetIsFullyLoaded(); +} + +inline MethodTable* TypeHandle::GetMethodTableOfElementType() const +{ + LIMITED_METHOD_CONTRACT; + + if (IsTypeDesc()) + { + TypeHandle elementType = AsTypeDesc()->GetTypeParam(); + return elementType.GetMethodTableOfElementType(); + } + else + { + return AsMethodTable(); + } +} + +inline MethodTable * TypeHandle::GetPossiblySharedArrayMethodTable() const +{ + LIMITED_METHOD_CONTRACT; + + _ASSERTE(IsArrayType()); + + if (IsArray()) + return AsArray()->GetTemplateMethodTable(); + else + return AsMethodTable(); +} + +inline TypeHandle TypeHandle::GetElementType() const +{ + LIMITED_METHOD_CONTRACT; + + if (IsTypeDesc()) + { + if (IsGenericVariable()) + return *this; + + return AsTypeDesc()->GetTypeParam().GetElementType(); + } + else + { + return *this; + } +} + +inline BOOL TypeHandle::IsZapped() const +{ + LIMITED_METHOD_DAC_CONTRACT; + + return (GetZapModule() != NULL); +} + +inline PTR_ArrayTypeDesc TypeHandle::AsArray() const +{ + LIMITED_METHOD_DAC_CONTRACT; + + _ASSERTE(IsArray()); + + PTR_ArrayTypeDesc result = PTR_ArrayTypeDesc(m_asTAddr - 2); + PREFIX_ASSUME(result != NULL); + return result; +} + +// Methods to allow you get get a the two possible representations +inline PTR_MethodTable TypeHandle::AsMethodTable() const +{ + LIMITED_METHOD_DAC_CONTRACT; + + _ASSERTE(!IsTypeDesc()); + + return PTR_MethodTable(m_asTAddr); +} + +inline PTR_TypeDesc TypeHandle::AsTypeDesc() const +{ + LIMITED_METHOD_DAC_CONTRACT; + + _ASSERTE(IsTypeDesc()); + + PTR_TypeDesc result = PTR_TypeDesc(m_asTAddr - 2); + PREFIX_ASSUME(result != NULL); + return result; +} + +inline FnPtrTypeDesc* TypeHandle::AsFnPtrType() const +{ + LIMITED_METHOD_DAC_CONTRACT; + + _ASSERTE(IsFnPtrType()); + + FnPtrTypeDesc* result = PTR_FnPtrTypeDesc(m_asTAddr - 2); + PREFIX_ASSUME(result != NULL); + return result; +} + +inline TypeVarTypeDesc* TypeHandle::AsGenericVariable() const +{ + LIMITED_METHOD_DAC_CONTRACT; + + _ASSERTE(IsGenericVariable()); + + TypeVarTypeDesc* result = PTR_TypeVarTypeDesc(m_asTAddr - 2); + PREFIX_ASSUME(result != NULL); + return result; +} + +inline BOOL TypeHandle::IsNativeValueType() const +{ + LIMITED_METHOD_DAC_CONTRACT; + return (IsTypeDesc() && AsTypeDesc()->IsNativeValueType()); +} + +inline MethodTable *TypeHandle::AsNativeValueType() const +{ + LIMITED_METHOD_CONTRACT; + + _ASSERTE(IsNativeValueType()); + return AsTypeDesc()->GetMethodTable(); +} + +inline BOOL TypeHandle::IsTypicalTypeDefinition() const +{ + LIMITED_METHOD_CONTRACT; + + return !HasInstantiation() || IsGenericTypeDefinition(); +} + +inline BOOL TypeHandle::SupportsGenericInterop(InteropKind interopKind) const +{ + LIMITED_METHOD_CONTRACT; + return (!IsTypeDesc() && AsMethodTable()->SupportsGenericInterop(interopKind)); +} + +inline BOOL TypeHandle::HasTypeEquivalence() const +{ + LIMITED_METHOD_CONTRACT; + + if (IsTypeDesc()) + return AsTypeDesc()->HasTypeEquivalence(); + else + return AsMethodTable()->HasTypeEquivalence(); +} + + +//-------------------------------------------------------------------------------------- +// IsEquivalentTo is based on Guid and TypeIdentifier attributes to support the "no-PIA" +// feature. The idea is that compilers pull types from the PIA into different assemblies +// and these types - represented by separate MTs/TypeHandles - are considered equivalent +// for certain operations. + + +#ifndef DACCESS_COMPILE +inline BOOL TypeHandle::IsEquivalentTo(TypeHandle type COMMA_INDEBUG(TypeHandlePairList *pVisited /*= NULL*/)) const +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_ANY; + SO_TOLERANT; + } + CONTRACTL_END; + + if (*this == type) + return TRUE; + +#ifdef FEATURE_TYPEEQUIVALENCE + // bail early for normal types + if (!HasTypeEquivalence() || !type.HasTypeEquivalence()) + return FALSE; + + if (IsTypeDesc()) + return AsTypeDesc()->IsEquivalentTo(type COMMA_INDEBUG(pVisited)); + + if (type.IsTypeDesc()) + return FALSE; + + return AsMethodTable()->IsEquivalentTo_Worker(type.AsMethodTable() COMMA_INDEBUG(pVisited)); +#else + return FALSE; +#endif +} +#endif + +// Execute the callback functor for each MethodTable that makes up the given type handle. This method +// does not invoke the functor for generic variables +template<class T> +inline void TypeHandle::ForEachComponentMethodTable(T &callback) const +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_ANY; + } + CONTRACTL_END; + + if (IsTypeDesc() && AsTypeDesc()->HasTypeParam()) + { + // If we have a type parameter, then we just need to invoke ourselves on that parameter + AsTypeDesc()->GetTypeParam().ForEachComponentMethodTable(callback); + } + else if (IsFnPtrType()) + { + // If we are a function pointer, then we need to invoke the callback method on the function + // pointer's return type as well as each of its argument types + FnPtrTypeDesc *pFnPtr = AsFnPtrType(); + for (DWORD iArg = 0; iArg < pFnPtr->GetNumArgs() + 1; ++iArg) + { + pFnPtr->GetRetAndArgTypesPointer()[iArg].ForEachComponentMethodTable(callback); + } + } + else if (HasInstantiation()) + { + // If we have a generic instantiation, we need to invoke the callback on each of the generic + // parameters as well as the root method table. + callback(GetMethodTable()); + + Instantiation instantiation = GetInstantiation(); + for (DWORD iGenericArg = 0; iGenericArg < instantiation.GetNumArgs(); ++iGenericArg) + { + instantiation[iGenericArg].ForEachComponentMethodTable(callback); + } + } + else if (IsGenericVariable()) + { + // We don't invoke the callback on generic variables since they don't have method tables + return; + } + else + { + // Otherwise, we must be a simple type, so just do the callback directly on the method table + callback(GetMethodTable()); + } +} + + +#endif // _TYPEHANDLE_INL_ + |