return new MdUtf8String(_GetUtf8Name(method));
}
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern bool MatchesNameHash(RuntimeMethodHandleInternal method, uint hash);
-
[DebuggerStepThrough]
[DebuggerHidden]
[MethodImpl(MethodImplOptions.InternalCall)]
internal static MdUtf8String GetUtf8Name(RuntimeFieldHandleInternal field) { return new MdUtf8String(_GetUtf8Name(field)); }
[MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern bool MatchesNameHash(RuntimeFieldHandleInternal handle, uint hash);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
internal static extern FieldAttributes GetAttributes(RuntimeFieldHandleInternal field);
[MethodImpl(MethodImplOptions.InternalCall)]
{
private readonly MdUtf8String m_name;
private readonly MemberListType m_listType;
- private readonly uint m_nameHash;
public unsafe Filter(byte* pUtf8Name, int cUtf8Name, MemberListType listType)
{
m_name = new MdUtf8String(pUtf8Name, cUtf8Name);
m_listType = listType;
- m_nameHash = 0;
-
- if (RequiresStringComparison())
- {
- m_nameHash = m_name.HashCaseInsensitive();
- }
}
public bool Match(MdUtf8String name)
// Does the current match type require a string comparison?
// If not, we know Match will always return true and the call can be skipped
- // If so, we know we can have a valid hash to check against from GetHashToMatch
public bool RequiresStringComparison()
{
return (m_listType == MemberListType.CaseSensitive) ||
}
public bool CaseSensitive() => m_listType == MemberListType.CaseSensitive;
-
- public uint GetHashToMatch()
- {
- Debug.Assert(RequiresStringComparison());
-
- return m_nameHash;
- }
}
private sealed class MemberInfoCache<T> where T : MemberInfo
{
if (filter.RequiresStringComparison())
{
- if (!RuntimeMethodHandle.MatchesNameHash(methodHandle, filter.GetHashToMatch()))
- {
- Debug.Assert(!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)));
- continue;
- }
-
if (!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)))
continue;
}
{
if (filter.RequiresStringComparison())
{
- if (!RuntimeMethodHandle.MatchesNameHash(methodHandle, filter.GetHashToMatch()))
- {
- Debug.Assert(!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)));
- continue;
- }
-
if (!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)))
continue;
}
{
if (filter.RequiresStringComparison())
{
- if (!RuntimeMethodHandle.MatchesNameHash(methodHandle, filter.GetHashToMatch()))
- {
- Debug.Assert(!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)));
- continue;
- }
-
if (!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)))
continue;
}
if (filter.RequiresStringComparison())
{
- if (!RuntimeFieldHandle.MatchesNameHash(runtimeFieldHandle, filter.GetHashToMatch()))
- {
- Debug.Assert(!filter.Match(RuntimeFieldHandle.GetUtf8Name(runtimeFieldHandle)));
- continue;
- }
-
if (!filter.Match(RuntimeFieldHandle.GetUtf8Name(runtimeFieldHandle)))
continue;
}
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool EqualsCaseInsensitive(void* szLhs, void* szRhs, int cSz);
- [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MdUtf8String_HashCaseInsensitive")]
- private static partial uint HashCaseInsensitive(void* sz, int cSz);
-
private readonly byte* m_pStringHeap; // This is the raw UTF8 string.
private readonly int m_StringHeapByteLength;
}
}
- internal uint HashCaseInsensitive()
- {
- return HashCaseInsensitive(m_pStringHeap, m_StringHeapByteLength);
- }
-
public override string ToString()
=> Encoding.UTF8.GetString(new ReadOnlySpan<byte>(m_pStringHeap, m_StringHeapByteLength));
}
FCFuncElement("GetMethodDef", RuntimeMethodHandle::GetMethodDef)
FCFuncElement("GetName", RuntimeMethodHandle::GetName)
FCFuncElement("_GetUtf8Name", RuntimeMethodHandle::GetUtf8Name)
- FCFuncElement("MatchesNameHash", RuntimeMethodHandle::MatchesNameHash)
FCFuncElement("HasMethodInstantiation", RuntimeMethodHandle::HasMethodInstantiation)
FCFuncElement("IsGenericMethodDefinition", RuntimeMethodHandle::IsGenericMethodDefinition)
FCFuncElement("GetGenericParameterCount", RuntimeMethodHandle::GetGenericParameterCount)
FCFuncElement("SetValueDirect", RuntimeFieldHandle::SetValueDirect)
FCFuncElement("GetName", RuntimeFieldHandle::GetName)
FCFuncElement("_GetUtf8Name", RuntimeFieldHandle::GetUtf8Name)
- FCFuncElement("MatchesNameHash", RuntimeFieldHandle::MatchesNameHash)
FCFuncElement("GetAttributes", RuntimeFieldHandle::GetAttributes)
FCFuncElement("GetApproxDeclaringType", RuntimeFieldHandle::GetApproxDeclaringType)
FCFuncElement("GetToken", RuntimeFieldHandle::GetToken)
_ASSERTE(fIsStatic || (!fIsRVA && !fIsThreadLocal));
_ASSERTE(fIsRVA + fIsThreadLocal <= 1);
- m_requiresFullMbValue = 0;
SetMemberDef(mb);
// A TypedByRef should be treated like a regular value type.
return CorTypeInfo::IsByRef_NoThrow(GetFieldType());
}
-BOOL FieldDesc::MightHaveName(ULONG nameHashValue)
-{
- LIMITED_METHOD_CONTRACT;
-
- // We only have space for a name hash when we are using the packed mb layout
- if (m_requiresFullMbValue)
- {
- return TRUE;
- }
-
- ULONG thisHashValue = m_mb & enum_packedMbLayout_NameHashMask;
-
- // A zero value might mean no hash has ever been set
- // (checking this way is better than dedicating a bit to tell us)
- if (thisHashValue == 0)
- {
- return TRUE;
- }
-
- ULONG testHashValue = nameHashValue & enum_packedMbLayout_NameHashMask;
-
- return (thisHashValue == testHashValue);
-}
-
#ifndef DACCESS_COMPILE //we don't require DAC to special case simple types
// Return the type of the field, as a class, but only if it's loaded.
TypeHandle FieldDesc::LookupFieldTypeHandle(ClassLoadLevel level, BOOL dropGenericArgumentLevel)
unsigned m_dword1;
struct {
#endif
- // Note that we may store other information in the high bits if available --
- // see enum_packedMBLayout and m_requiresFullMbValue for details.
unsigned m_mb : 24;
// 8 bits...
unsigned m_isThreadLocal : 1;
unsigned m_isRVA : 1;
unsigned m_prot : 3;
- // Does this field's mb require all 24 bits
- unsigned m_requiresFullMbValue : 1;
#if defined(DACCESS_COMPILE)
};
};
m_isThreadLocal = sourceField.m_isThreadLocal;
m_isRVA = sourceField.m_isRVA;
m_prot = sourceField.m_prot;
- m_requiresFullMbValue = sourceField.m_requiresFullMbValue;
m_dwOffset = sourceField.m_dwOffset;
m_type = sourceField.m_type;
BOOL fIsThreadLocal,
LPCSTR pszFieldName);
- enum {
- enum_packedMbLayout_MbMask = 0x01FFFF,
- enum_packedMbLayout_NameHashMask = 0xFE0000
- };
-
void SetMemberDef(mdFieldDef mb)
{
WRAPPER_NO_CONTRACT;
-
- // Check if we have to avoid using the packed mb layout
- if (RidFromToken(mb) > enum_packedMbLayout_MbMask)
- {
- m_requiresFullMbValue = 1;
- }
-
- // Set only the portion of m_mb we are using
- if (!m_requiresFullMbValue)
- {
- m_mb &= ~enum_packedMbLayout_MbMask;
- m_mb |= RidFromToken(mb);
- }
- else
- {
- m_mb = RidFromToken(mb);
- }
+ m_mb = RidFromToken(mb);
}
mdFieldDef GetMemberDef() const
{
LIMITED_METHOD_DAC_CONTRACT;
-
- // Check if this FieldDesc is using the packed mb layout
- if (!m_requiresFullMbValue)
- {
- return TokenFromRid(m_mb & enum_packedMbLayout_MbMask, mdtFieldDef);
- }
-
return TokenFromRid(m_mb, mdtFieldDef);
}
return GetMDImport()->GetNameOfFieldDef(GetMemberDef(), pszName);
}
- BOOL MightHaveName(ULONG nameHashValue);
-
// <TODO>@TODO: </TODO>This is slow, don't use it!
DWORD GetAttributes()
{
// Retrieve the right comparison function to use.
UTF8StringCompareFuncPtr StrCompFunc = FM_GetStrCompFunc(flags);
- SString targetName(SString::Utf8Literal, pszName);
- ULONG targetNameHash = targetName.HashCaseInsensitive();
-
// Statistically it's most likely for a method to be found in non-vtable portion of this class's members, then in the
// vtable of this class's declared members, then in the inherited portion of the vtable, so we search backwards.
}
if ((flags & FM_IgnoreName) != 0
- ||
- (pCurDeclMD->MightHaveName(targetNameHash)
- // This is done last since it is the most expensive of the IF statement.
- && StrCompFunc(pszName, pCurDeclMD->GetNameThrowing()) == 0)
- )
+ || StrCompFunc(pszName, pCurDeclMD->GetNameThrowing()) == 0)
{
if (CompareMethodSigWithCorrectSubstitution(pSignature, cSignature, pModule, pCurDeclMD, pDefSubst, pMT))
{
// Retrieve the right comparison function to use.
UTF8StringCompareFuncPtr StrCompFunc = FM_GetStrCompFunc(flags);
- SString targetName(SString::Utf8, pszName);
- ULONG targetNameHash = targetName.HashCaseInsensitive();
-
// Scan all classes in the hierarchy, starting at the current class and
// moving back up towards the base.
while (pMT != NULL)
continue;
}
- if (pCurMD->MightHaveName(targetNameHash) && StrCompFunc(pszName, pCurMD->GetNameOnNonArrayClass()) == 0)
+ if (StrCompFunc(pszName, pCurMD->GetNameOnNonArrayClass()) == 0)
{
if (pRetMD != NULL)
{
if (pMT->IsArray())
return NULL;
- SString targetName(SString::Utf8Literal, pszName);
- ULONG targetNameHash = targetName.HashCaseInsensitive();
-
EEClass * pClass = pMT->GetClass();
MethodTable *pParentMT = pMT->GetParentMethodTable();
// Check is valid FieldDesc, and not some random memory
INDEBUGIMPL(pFD->GetApproxEnclosingMethodTable()->SanityCheck());
- if (!pFD->MightHaveName(targetNameHash))
- {
- continue;
- }
-
IfFailThrow(pInternalImport->GetNameOfFieldDef(mdField, &szMemberName));
if (StrCompFunc(szMemberName, pszName) != 0)
#endif
//*******************************************************************************
-BOOL MethodDesc::MightHaveName(ULONG nameHashValue)
-{
- LIMITED_METHOD_CONTRACT;
-
- // We only have space for a name hash when we are using the packed slot layout
- if (RequiresFullSlotNumber())
- {
- return TRUE;
- }
-
- WORD thisHashValue = m_wSlotNumber & enum_packedSlotLayout_NameHashMask;
-
- // A zero value might mean no hash has ever been set
- // (checking this way is better than dedicating a bit to tell us)
- if (thisHashValue == 0)
- {
- return TRUE;
- }
-
- WORD testHashValue = (WORD) nameHashValue & enum_packedSlotLayout_NameHashMask;
-
- return (thisHashValue == testHashValue);
-}
-
-//*******************************************************************************
void MethodDesc::GetSig(PCCOR_SIGNATURE *ppSig, DWORD *pcSig)
{
CONTRACTL
// Is the method synchronized
mdcSynchronized = 0x4000,
- // Does the method's slot number require all 16 bits
- mdcRequiresFullSlotNumber = 0x8000
+ // unused = 0x8000
};
#define METHOD_MAX_RVA 0x7FFFFFFF
LPCUTF8 GetNameThrowing();
- BOOL MightHaveName(ULONG nameHashValue);
-
FORCEINLINE LPCUTF8 GetNameOnNonArrayClass()
{
WRAPPER_NO_CONTRACT;
inline WORD GetSlot()
{
LIMITED_METHOD_DAC_CONTRACT;
-
- // Check if this MD is using the packed slot layout
- if (!RequiresFullSlotNumber())
- {
- return (m_wSlotNumber & enum_packedSlotLayout_SlotMask);
- }
-
return m_wSlotNumber;
}
inline VOID SetSlot(WORD wSlotNum)
{
LIMITED_METHOD_CONTRACT;
-
- // Check if we have to avoid using the packed slot layout
- if (wSlotNum > enum_packedSlotLayout_SlotMask)
- {
- SetRequiresFullSlotNumber();
- }
-
- // Set only the portion of m_wSlotNumber we are using
- if (!RequiresFullSlotNumber())
- {
- m_wSlotNumber &= ~enum_packedSlotLayout_SlotMask;
- m_wSlotNumber |= wSlotNum;
- }
- else
- {
- m_wSlotNumber = wSlotNum;
- }
+ m_wSlotNumber = wSlotNum;
}
inline BOOL IsVirtualSlot()
PTR_MethodDesc GetDeclMethodDesc(UINT32 slotNumber);
-protected:
- inline void SetRequiresFullSlotNumber()
- {
- LIMITED_METHOD_CONTRACT;
- m_wFlags |= mdcRequiresFullSlotNumber;
- }
-
- inline DWORD RequiresFullSlotNumber()
- {
- LIMITED_METHOD_DAC_CONTRACT;
- return (m_wFlags & mdcRequiresFullSlotNumber) != 0;
- }
-
public:
mdMethodDef GetMemberDef() const;
mdMethodDef GetMemberDef_NoLogging() const;
BYTE m_bFlags2;
// The slot number of this MethodDesc in the vtable array.
- // Note that we may store other information in the high bits if available --
- // see enum_packedSlotLayout and mdcRequiresFullSlotNumber for details.
WORD m_wSlotNumber;
-
- enum {
- enum_packedSlotLayout_SlotMask = 0x03FF,
- enum_packedSlotLayout_NameHashMask = 0xFC00
- };
-
WORD m_wFlags;
-
-
public:
#ifdef DACCESS_COMPILE
void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
DllImportEntry(TypeBuilder_SetConstantValue)
DllImportEntry(TypeBuilder_DefineCustomAttribute)
DllImportEntry(MdUtf8String_EqualsCaseInsensitive)
- DllImportEntry(MdUtf8String_HashCaseInsensitive)
DllImportEntry(TypeName_ReleaseTypeNameParser)
DllImportEntry(TypeName_CreateTypeNameParser)
DllImportEntry(TypeName_GetNames)
return fStringsEqual;
}
-extern "C" ULONG QCALLTYPE MdUtf8String_HashCaseInsensitive(LPCUTF8 sz, INT32 stringNumBytes)
-{
- QCALL_CONTRACT;
-
- // Important: the string in pSsz isn't null terminated so the length must be used
- // when performing operations on the string.
-
- ULONG hashValue = 0;
-
- BEGIN_QCALL;
-
- StackSString str(SString::Utf8, sz, stringNumBytes);
- hashValue = str.HashCaseInsensitive();
-
- END_QCALL;
-
- return hashValue;
-}
-
static BOOL CheckCAVisibilityFromDecoratedType(MethodTable* pCAMT, MethodDesc* pCACtor, MethodTable* pDecoratedMT, Module* pDecoratedModule)
{
CONTRACTL
FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
FnPtrTypeDesc* fnPtr = typeHandle.AsFnPtrType();
-
+
HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
{
MethodTable *pMT = CoreLibBinder::GetClass(CLASS__TYPE);
{
TypeHandle typeHandle = fnPtr->GetRetAndArgTypes()[position];
OBJECTREF refType = typeHandle.GetManagedClassObject();
- gc.retVal->SetAt(position, refType);
+ gc.retVal->SetAt(position, refType);
}
}
HELPER_METHOD_FRAME_END();
FnPtrTypeDesc* fnPtr = typeHandle.AsFnPtrType();
unmanaged = (fnPtr->GetCallConv() & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_UNMANAGED;
}
-
+
FC_RETURN_BOOL(unmanaged);
}
FCIMPLEND
}
FCIMPLEND
-FCIMPL2(FC_BOOL_RET, RuntimeMethodHandle::MatchesNameHash, MethodDesc * pMethod, ULONG hash)
-{
- FCALL_CONTRACT;
-
- FC_RETURN_BOOL(pMethod->MightHaveName(hash));
-}
-FCIMPLEND
-
FCIMPL1(StringObject*, RuntimeMethodHandle::GetName, MethodDesc *pMethod) {
CONTRACTL {
FCALL_CHECK;
pMethod, declType.GetClassOrArrayInstantiation(), pMethod->LoadMethodInstantiation(), &typeContext);
else
SigTypeContext::InitTypeContext(declType, &typeContext);
-
+
MetaSig msig(pCorSig, cCorSig, pModule, &typeContext,
(callConv & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_FIELD ? MetaSig::sigField : MetaSig::sigMember);
}
FCIMPLEND
-FCIMPL2(FC_BOOL_RET, RuntimeFieldHandle::MatchesNameHash, FieldDesc * pField, ULONG hash)
-{
- FCALL_CONTRACT;
-
- FC_RETURN_BOOL(pField->MightHaveName(hash));
-}
-FCIMPLEND
-
FCIMPL1(INT32, RuntimeFieldHandle::GetAttributes, FieldDesc *pField) {
CONTRACTL {
FCALL_CHECK;
extern "C" BOOL QCALLTYPE MdUtf8String_EqualsCaseInsensitive(LPCUTF8 szLhs, LPCUTF8 szRhs, INT32 stringNumBytes);
-extern "C" ULONG QCALLTYPE MdUtf8String_HashCaseInsensitive(LPCUTF8 sz, INT32 stringNumBytes);
-
class RuntimeTypeHandle;
typedef RuntimeTypeHandle FCALLRuntimeTypeHandle;
static FCDECL1(Object *, GetArgumentTypesFromFunctionPointer, ReflectClassBaseObject *pTypeUNSAFE);
static FCDECL1(FC_BOOL_RET, IsUnmanagedFunctionPointer, ReflectClassBaseObject *pTypeUNSAFE);
-
+
static FCDECL2(FC_BOOL_RET, CanCastTo, ReflectClassBaseObject *pType, ReflectClassBaseObject *pTarget);
static FCDECL2(FC_BOOL_RET, IsInstanceOfType, ReflectClassBaseObject *pType, Object *object);
static FCDECL1(INT32, GetMethodDef, ReflectMethodObject *pMethodUNSAFE);
static FCDECL1(StringObject*, GetName, MethodDesc *pMethod);
static FCDECL1(LPCUTF8, GetUtf8Name, MethodDesc *pMethod);
- static FCDECL2(FC_BOOL_RET, MatchesNameHash, MethodDesc * pMethod, ULONG hash);
static
FCDECL1(FC_BOOL_RET, HasMethodInstantiation, MethodDesc *pMethod);
static FCDECL5(void, SetValueDirect, ReflectFieldObject *pFieldUNSAFE, ReflectClassBaseObject *pFieldType, TypedByRef *pTarget, Object *valueUNSAFE, ReflectClassBaseObject *pContextType);
static FCDECL1(StringObject*, GetName, ReflectFieldObject *pFieldUNSAFE);
static FCDECL1(LPCUTF8, GetUtf8Name, FieldDesc *pField);
- static FCDECL2(FC_BOOL_RET, MatchesNameHash, FieldDesc * pField, ULONG hash);
static FCDECL1(INT32, GetAttributes, FieldDesc *pField);
static FCDECL1(ReflectClassBaseObject*, GetApproxDeclaringType, FieldDesc *pField);