TypeHandle Binder::LookupType(BinderTypeID id, BOOL fLoad) { _ASSERTE(m_pModule != NULL); _ASSERTE(id != TYPE__NIL); _ASSERTE(id <= m_cTypeHandles); THROWSCOMPLUSEXCEPTION(); TypeHandle th; const TypeDescription *d = m_typeDescriptions + id - 1; OBJECTREF pThrowable = NULL; GCPROTECT_BEGIN(pThrowable); NameHandle nh(d->type, TypeHandle(GetClass(d->classID)), d->rank); if (!fLoad) nh.SetTokenNotToLoad(tdAllTypes); th = m_pModule->GetClassLoader()->FindTypeHandle(&nh, &pThrowable); GCPROTECT_END(); if (th.IsNull()) { if (fLoad) COMPlusThrow(pThrowable); return TypeHandle(); } m_pTypeHandles[id-1] = th; return th; }
void QCALLTYPE COMDynamicWrite::TermCreateClass(QCall::ModuleHandle pModule, INT32 tk, QCall::ObjectHandleOnStack retType) { QCALL_CONTRACT; TypeHandle typeHnd; BEGIN_QCALL; _ASSERTE(pModule->GetReflectionModule()->GetClassWriter()); // Use the same service, regardless of whether we are generating a normal // class, or the special class for the module that holds global functions // & methods. pModule->GetReflectionModule()->AddClass(tk); // manually load the class if it is not the global type if (!IsNilToken(tk)) { TypeKey typeKey(pModule, tk); typeHnd = pModule->GetClassLoader()->LoadTypeHandleForTypeKey(&typeKey, TypeHandle()); } if (!typeHnd.IsNull()) { GCX_COOP(); retType.Set(typeHnd.GetManagedClassObject()); } END_QCALL; return; }
TypeHandle Binder::RawGetType(BinderTypeID id) { CANNOTTHROWCOMPLUSEXCEPTION(); _ASSERTE(m_pModule != NULL); _ASSERTE(id != TYPE__NIL); _ASSERTE(id <= m_cTypeHandles); TypeHandle th = m_pTypeHandles[id-1]; _ASSERTE(!th.IsNull()); return th; }
MethodTable *Binder::RawGetClass(BinderClassID id) { CANNOTTHROWCOMPLUSEXCEPTION(); _ASSERTE(m_pModule != NULL); _ASSERTE(id != CLASS__NIL); _ASSERTE(id <= m_cClassRIDs); TypeHandle th = m_pModule->LookupTypeDef(TokenFromRid(m_pClassRIDs[id-1], mdtTypeDef)); _ASSERTE(!th.IsNull()); _ASSERTE(th.IsUnsharedMT()); return th.AsMethodTable(); }
TypeHandle Binder::FetchType(BinderTypeID id) { THROWSCOMPLUSEXCEPTION(); _ASSERTE(id != TYPE__NIL); _ASSERTE(id <= m_cTypeHandles); TypeHandle th = m_pTypeHandles[id-1]; if (th.IsNull()) th = LookupType(id); return th; }
void Binder::CheckMscorlib() { const FieldOffsetCheck *pOffsets = MscorlibFieldOffsets; while (pOffsets->fieldID != FIELD__NIL) { FieldDesc *pFD = g_Mscorlib.FetchField(pOffsets->fieldID); DWORD offset = pFD->GetOffset(); if (!pFD->GetMethodTableOfEnclosingClass()->IsValueClass()) offset += sizeof(ObjHeader); _ASSERTE(offset == pOffsets->expectedOffset && "Managed class field offset does not match unmanaged class field offset"); pOffsets++; } const ClassSizeCheck *pSizes = MscorlibClassSizes; while (pSizes->classID != CLASS__NIL) { MethodTable *pMT = g_Mscorlib.FetchClass(pSizes->classID); DWORD size = pMT->GetClass()->GetNumInstanceFieldBytes(); DWORD expected = pSizes->expectedSize - sizeof(void*); _ASSERTE(size == expected && "Managed object size does not match unmanaged object size"); pSizes++; } // check the consistency of BCL and VM // note: it is not enabled by default because of it is time consuming and // changes the bootstrap sequence of the EE if (!g_pConfig->GetConfigDWORD(L"ConsistencyCheck", 0)) return; // // VM referencing BCL (mscorlib.h) // for (BinderClassID cID = (BinderClassID) 1; cID <= g_Mscorlib.m_cClassRIDs; cID = (BinderClassID) (cID + 1)) { if (g_Mscorlib.GetClassName(cID) != NULL) // Allow for CorSigElement entries with no classes g_Mscorlib.FetchClass(cID); } for (BinderMethodID mID = (BinderMethodID) 1; mID <= g_Mscorlib.m_cMethodRIDs; mID = (BinderMethodID) (mID + 1)) g_Mscorlib.FetchMethod(mID); for (BinderFieldID fID = (BinderFieldID) 1; fID <= g_Mscorlib.m_cFieldRIDs; fID = (BinderFieldID) (fID + 1)) g_Mscorlib.FetchField(fID); // // BCL referencing VM (ecall.cpp) // HRESULT hr = S_OK; Module *pModule = g_Mscorlib.m_pModule; IMDInternalImport *pInternalImport = pModule->GetMDImport(); HENUMInternal hEnum; // for all methods... IfFailGo(pInternalImport->EnumAllInit(mdtMethodDef, &hEnum)); for (;;) { mdTypeDef td; mdTypeDef tdClass; DWORD dwImplFlags; if (!pInternalImport->EnumNext(&hEnum, &td)) break; pInternalImport->GetMethodImplProps(td, NULL, &dwImplFlags); // ... that are internal calls ... if (!IsMiInternalCall(dwImplFlags)) continue; IfFailGo(pInternalImport->GetParentToken(td, &tdClass)); NameHandle className(pModule, tdClass); TypeHandle type; type = pModule->GetClassLoader()->LoadTypeHandle(&className, RETURN_ON_ERROR, FALSE); if (type.IsNull()) { LPCUTF8 pszName = pInternalImport->GetNameOfMethodDef(tdClass); OutputDebugStringA(pszName); OutputDebugStringA("\n"); _ASSERTE(false); } MethodDesc *pMD = type.AsMethodTable()->GetClass()->FindMethod(td);; _ASSERTE(pMD); // ... check that the method is in the fcall table. if (GetIDForMethod(pMD) == 0xffff) { LPCUTF8 pszName = pInternalImport->GetNameOfMethodDef(td); OutputDebugStringA(pszName); OutputDebugStringA("\n"); _ASSERTE(false); } } pInternalImport->EnumClose(&hEnum); ErrExit: _ASSERTE(SUCCEEDED(hr)); }