int GetVersionResilientTypeHashCode(TypeHandle type) { if (!type.IsTypeDesc()) { MethodTable *pMT = type.AsMethodTable(); _ASSERTE(!pMT->IsArray()); _ASSERTE(!IsNilToken(pMT->GetCl())); LPCUTF8 szNamespace; LPCUTF8 szName; IfFailThrow(pMT->GetMDImport()->GetNameOfTypeDef(pMT->GetCl(), &szName, &szNamespace)); int hashcode = ComputeNameHashCode(szNamespace, szName); MethodTable *pMTEnclosing = pMT->LoadEnclosingMethodTable(CLASS_LOAD_UNRESTOREDTYPEKEY); if (pMTEnclosing != NULL) { hashcode = ComputeNestedTypeHashCode(GetVersionResilientTypeHashCode(TypeHandle(pMTEnclosing)), hashcode); } if (!pMT->IsGenericTypeDefinition() && pMT->HasInstantiation()) { return ComputeGenericInstanceHashCode(hashcode, pMT->GetInstantiation().GetNumArgs(), pMT->GetInstantiation(), GetVersionResilientTypeHashCode); } else { return hashcode; } } else if (type.IsArray()) { ArrayTypeDesc *pArray = type.AsArray(); return ComputeArrayTypeHashCode(GetVersionResilientTypeHashCode(pArray->GetArrayElementTypeHandle()), pArray->GetRank()); } else if (type.IsPointer()) { return ComputePointerTypeHashCode(GetVersionResilientTypeHashCode(type.AsTypeDesc()->GetTypeParam())); } else if (type.IsByRef()) { return ComputeByrefTypeHashCode(GetVersionResilientTypeHashCode(type.AsTypeDesc()->GetTypeParam())); } assert(false); return 0; }
void SigTypeContext::InitTypeContext(MethodDesc *md, Instantiation exactClassInst, Instantiation exactMethodInst, SigTypeContext *pRes) { LIMITED_METHOD_CONTRACT; STATIC_CONTRACT_SO_TOLERANT; MethodTable *pMT = md->GetMethodTable(); if (pMT->IsArray()) { pRes->m_classInst = exactClassInst.IsEmpty() ? pMT->GetClassOrArrayInstantiation() : exactClassInst; } else { pRes->m_classInst = exactClassInst; } pRes->m_methodInst = exactMethodInst; }
extern "C" Object * __isinst_class(void * p, MethodTable * pTargetMT) { Object * o = (Object *)p; if (o == NULL) return o; MethodTable * pMT = o->RawGetMethodTable(); do { if (pMT == pTargetMT) return o; if (pMT->IsArray()) break; pMT = pMT->GetParent(); } while (pMT); // TODO: Handle corner cases return NULL; }
extern "C" Object * __castclass_class(void * p, MethodTable * pTargetMT) { Object * o = (Object *)p; if (o == NULL) return o; MethodTable * pMT = o->RawGetMethodTable(); do { if (pMT == pTargetMT) return o; if (pMT->IsArray()) break; pMT = pMT->GetParent(); } while (pMT); // TODO: Handle corner cases, throw proper exception throw "__castclass_class"; }