//***************************************************************************** // Check the given token to see if it has moved to a new location. If so, // return true and give back the new token. //***************************************************************************** int CeeGenTokenMapper::HasTokenMoved( mdToken tkFrom, mdToken &tkTo) { mdToken tk; int i = IndexForType(tkFrom); if(i == -1) return false; _ASSERTE(i < GetMaxMapSize()); TOKENMAP *pMap = &m_rgMap[i]; // Assume nothing moves. tkTo = tkFrom; // If the array is smaller than the index, can't have moved. if ((ULONG) pMap->Count() <= RidFromToken(tkFrom)) return (false); // If the entry is set to 0, then nothing there. tk = *pMap->Get(RidFromToken(tkFrom)); if (tk == mdTokenNil) return (false); // Had to move to a new location, return that new location. tkTo = tk; return (true); }
HRESULT CAsmLink::AddImport(mdAssembly AssemblyID, mdToken ImportToken, DWORD dwFlags, mdFile * pFileToken) { // If we have already emitted the manifest, and then we import // a file with a CA that maps to an assembly option, we're in trouble! ASSERT(m_bInited && !m_bPreClosed && !m_bManifestEmitted); HRESULT hr; CFile *file = NULL; if (TypeFromToken(ImportToken) == mdtModule) { ASSERT(RidFromToken(ImportToken) < m_pModules->CountFiles()); hr = m_pModules->GetFile( ImportToken, &file); } else { ASSERT(TypeFromToken(ImportToken) == mdtAssemblyRef && RidFromToken(ImportToken) < m_pImports->CountFiles()); hr = m_pImports->GetFile( ImportToken, &file); } if (FAILED(hr)) return hr; ASSERT(file != NULL); if (FAILED(hr = m_pAssem->AddFile(file, dwFlags, pFileToken))) return hr; else if (AssemblyID == AssemblyIsUBM) { if (pFileToken) *pFileToken = ImportToken; return S_FALSE; } ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1)); if (FAILED(hr = m_pModules->RemoveFile( ImportToken))) return hr; if (FAILED(hr = file->ImportFile( NULL, m_pAssem))) return hr; return file->ImportResources(m_pAssem); }
//***************************************************************************** // cascading Mark of a MemberRef //***************************************************************************** HRESULT FilterManager::MarkMemberRef(mdMemberRef mr) { HRESULT hr = NOERROR; MemberRefRec *pRec; ULONG cbSize; ULONG cbUsed; PCCOR_SIGNATURE pbSig; IHostFilter *pFilter = m_pMiniMd->GetHostFilter(); mdToken md; TOKENMAP *tkMap; mdToken tkParent; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); // if MemberRef is already marked, just return if (m_pMiniMd->GetFilterTable()->IsMemberRefMarked(mr)) goto ErrExit; IfFailGo( m_pMiniMd->GetFilterTable()->MarkMemberRef( mr ) ); if (pFilter) pFilter->MarkToken(mr); IfFailGo(m_pMiniMd->GetMemberRefRecord(RidFromToken(mr), &pRec)); // we want to mark the parent of MemberRef as well tkParent = m_pMiniMd->getClassOfMemberRef(pRec); // If the parent is the global TypeDef, mark only the TypeDef itself (low-level function). // Other parents, do the transitive mark (ie, the high-level function). // if (IsGlobalTypeDef(tkParent)) IfFailGo( m_pMiniMd->GetFilterTable()->MarkTypeDef( tkParent ) ); else IfFailGo( Mark( tkParent ) ); // Walk the signature and mark all of the embedded types IfFailGo(m_pMiniMd->getSignatureOfMemberRef(pRec, &pbSig, &cbSize)); IfFailGo( MarkSignature(pbSig, cbSize, &cbUsed) ); tkMap = m_pMiniMd->GetMemberRefToMemberDefMap(); PREFIX_ASSUME(tkMap != NULL); md = *(tkMap->Get(RidFromToken(mr))); // can be fielddef or methoddef if ( RidFromToken(md) != mdTokenNil ) { // MemberRef is referring to either a FieldDef or MethodDef. // If it is referring to MethodDef, we have fix the parent of MemberRef to be the MethodDef. // However, if it is mapped to a FieldDef, the parent column does not track this information. // Therefore we need to mark it explicitly. // IfFailGo( Mark(md) ); } IfFailGo( MarkCustomAttributesWithParentToken(mr) ); ErrExit: return hr; } // HRESULT FilterManager::MarkMemberRef()
HRESULT CAsmLink::ImportTypes(mdAssembly AssemblyID, mdToken FileToken, DWORD dwScope, HALINKENUM* phEnum, IMetaDataImport **ppImportScope, DWORD* pdwCountOfTypes) { ASSERT(m_bInited && !m_bPreClosed); ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1) || AssemblyID == AssemblyIsUBM); ASSERT((TypeFromToken(FileToken) == mdtFile && RidFromToken(FileToken) < m_pAssem->CountFiles()) || (TypeFromToken(FileToken) == mdtAssemblyRef && RidFromToken(FileToken) < m_pImports->CountFiles()) || (TypeFromToken(FileToken) == mdtModule && RidFromToken(FileToken) < m_pModules->CountFiles()) || FileToken == AssemblyID); ASSERT(dwScope == 0 || TypeFromToken(FileToken) == mdtAssemblyRef); // Initialize to empty values if (ppImportScope) *ppImportScope = NULL; if (pdwCountOfTypes) *pdwCountOfTypes = 0; *phEnum = (HALINKENUM)NULL; HRESULT hr = S_OK; TypeEnumerator *TypeEnum = new TypeEnumerator; if (TypeEnum == NULL) return E_OUTOFMEMORY; TypeEnum->TypeID = 0; if (TypeFromToken(FileToken) == mdtAssemblyRef) { // Import from another assembly (possibly a nested file) if (SUCCEEDED(hr = m_pImports->GetFile( FileToken, &TypeEnum->file)) && dwScope > 0) { CAssemblyFile *assembly = (CAssemblyFile*)TypeEnum->file; TypeEnum->file = NULL; hr = assembly->GetFile(dwScope - 1, &TypeEnum->file); } } else if (TypeFromToken(FileToken) == mdtModule) { hr = m_pModules->GetFile( FileToken, &TypeEnum->file); } else if (TypeFromToken(FileToken) == mdtFile){ // Import from this Assembly hr = m_pAssem->GetFile( FileToken, &TypeEnum->file); } else { TypeEnum->file = m_pAssem; hr = S_OK; } if (SUCCEEDED(hr) && SUCCEEDED(hr = TypeEnum->file->ImportFile(pdwCountOfTypes, NULL))) { if ((ppImportScope != NULL) && (*ppImportScope = TypeEnum->file->GetImportScope())) (*ppImportScope)->AddRef(); // Give a copy to them, AddRef so they can release if (pdwCountOfTypes) *pdwCountOfTypes = TypeEnum->file->CountTypes(); *phEnum = (HALINKENUM)TypeEnum; if (hr == S_OK && TypeEnum->file->CountTypes() == 0) hr = S_FALSE; } else { delete TypeEnum; } return hr; }
/*************************************************************************** * Create a prototype object ***************************************************************************/ bool CSystemObject::InitializeVm( CCilVm& vm ) { int32_t iIndex = IndexFromBuiltinRid( vm.getSystemObjectRID() ); RID ridObjectName = vm.getMetaData().getBuiltinObjectTable()[ iIndex ].getObjectName(); assert( ridObjectName != RID_NOTDEFINED ); RID rid = vm.createPrototypeObject( vm.getSystemObjectRID(), ridObjectName, vm.getObjectRID() ); assert( rid == vm.getSystemObjectRID() ); VMOBJECTREF objref = vm.createObject( vm.getObjectRID() ); CVariable var; var.setObjectRef( objref ); //Set true as an object value.. CVariable varBool( true ); objref->setValue( varBool ); //Create ExitCode property CVariable varExitCode( 0 ); objref->setProperty( NAME_BUILTIN_SYSTEM_PROPERTY_EXITCODE, varExitCode ); //Create Environment property //Add properties of prototype object here vm.getPrototypeObject( vm.getSystemObjectRID() ).setProperty( NAME_BUILTIN_SYSTEM_PROPERTY_ENVIRONMENT, var ); //--------------------------------------------------------------------------- // Bind System functions //--------------------------------------------------------------------------- for( int32_t i = 0; i<sizeof( initParams ) / sizeof( initParams[ 0 ] ); ++i ) { int32_t iParams; iParams = (int32_t)RidFromToken( initParams[ i ].ridParam ); if( isBuiltinRid( initParams[ i ].ridParam ) ) { iParams = RidFromToken( -iParams ) - 1; } //----------------------------------------------------------------------- //Register methods //----------------------------------------------------------------------- bool b = vm.bindBuiltinMethod( wstring( initParams[ i ].pStrSymbol ), initParams[ i ].pMethod, iParams ); if( !b ) return false; } return true; }
/*************************************************************************** * Create a prototype object ***************************************************************************/ bool CArrayObject::InitializeVm( CCilVm& vm ) { int32_t iIndex = IndexFromBuiltinRid( vm.getArrayObjectRID() ); RID ridObjectName = vm.getMetaData().getBuiltinObjectTable()[ iIndex ].getObjectName(); assert( ridObjectName != RID_NOTDEFINED ); RID rid = vm.createPrototypeObject( vm.getArrayObjectRID(), ridObjectName, vm.getObjectRID() ); assert( rid == vm.getArrayObjectRID() ); //--------------------------------------------------------------------------- //Bind global object //--------------------------------------------------------------------------- CVmObject* pObj = vm.createObject( vm.getArrayObjectRID() ); CVariable obj( pObj, OPERAND_FLAG( OPERAND_FLAG_DONTDELETE | OPERAND_FLAG_DONTENUM | OPERAND_FLAG_READONLY ) ); //Set true as an object value.. CVariable var( true ); pObj->setValue( var ); CG_SYMBOL_INFORMATION info = vm.querySymbolInformation( NAME_BUILTIN_ARRAY_OBJECT ); vm.setStaticField( info.rid, obj, true ); //Force over write it //--------------------------------------------------------------------------- // Bind System functions //--------------------------------------------------------------------------- for( int32_t i = 0; i<sizeof( initParams ) / sizeof( initParams[ 0 ] ); ++i ) { int32_t iParams; iParams = (int32_t)RidFromToken( initParams[ i ].ridParam ); if( isBuiltinRid( initParams[ i ].ridParam ) ) { iParams = RidFromToken( -iParams ) - 1; } //----------------------------------------------------------------------- //Register methods //----------------------------------------------------------------------- bool b = vm.bindBuiltinMethod( wstring( initParams[ i ].pStrSymbol ), initParams[ i ].pMethod, iParams ); if( !b ) return false; } return true; }
MethodTable *Binder::LookupClass(BinderClassID id, BOOL fLoad) { _ASSERTE(m_pModule != NULL); _ASSERTE(id != CLASS__NIL); _ASSERTE(id <= m_cClassRIDs); MethodTable *pMT; const ClassDescription *d = m_classDescriptions + id - 1; NameHandle nh(d->name); if (!fLoad) { nh.SetTokenNotToLoad(tdAllTypes); pMT = m_pModule->GetClassLoader()->FindTypeHandle(&nh).AsMethodTable(); if (pMT == NULL) return NULL; } else { THROWSCOMPLUSEXCEPTION(); BEGIN_ENSURE_COOPERATIVE_GC(); OBJECTREF pThrowable = NULL; GCPROTECT_BEGIN(pThrowable); pMT = m_pModule->GetClassLoader()->FindTypeHandle(&nh, &pThrowable).AsMethodTable(); if (pMT == NULL) { _ASSERTE(!"EE expects class to exist"); COMPlusThrow(pThrowable); } GCPROTECT_END(); END_ENSURE_COOPERATIVE_GC(); } _ASSERTE(pMT->GetModule() == m_pModule); mdTypeDef td = pMT->GetClass()->GetCl(); _ASSERTE(!IsNilToken(td)); _ASSERTE(RidFromToken(td) <= USHRT_MAX); m_pClassRIDs[id-1] = (USHORT) RidFromToken(td); m_pModule->StoreTypeDef(td, pMT); return pMT; }
//***************************************************************************** // cascading Mark of all properties associated with a TypeDef token //***************************************************************************** HRESULT FilterManager::MarkPropertiesWithParentToken( mdTypeDef td) { HRESULT hr = NOERROR; RID ridPropertyMap; RID ulStart, ulEnd; RID index; PropertyMapRec *pPropertyMapRec; // get the starting/ending rid of properties of this typedef IfFailGo(m_pMiniMd->FindPropertyMapFor(RidFromToken(td), &ridPropertyMap)); if ( !InvalidRid(ridPropertyMap) ) { IfFailGo(m_pMiniMd->GetPropertyMapRecord(ridPropertyMap, &pPropertyMapRec)); ulStart = m_pMiniMd->getPropertyListOfPropertyMap( pPropertyMapRec ); IfFailGo(m_pMiniMd->getEndPropertyListOfPropertyMap(ridPropertyMap, &ulEnd)); for ( index = ulStart; index < ulEnd; index ++ ) { RID rid; IfFailGo(m_pMiniMd->GetPropertyRid(index, &rid)); IfFailGo(MarkProperty(TokenFromRid( rid, mdtProperty))); } } ErrExit: return hr; } // HRESULT FilterManager::MarkPropertiesWithParentToken()
//***************************************************************************** // cascading Mark of a Property token //***************************************************************************** HRESULT FilterManager::MarkProperty(mdProperty pr) { HRESULT hr = NOERROR; PropertyRec *pRec; ULONG cbSize; ULONG cbUsed; PCCOR_SIGNATURE pbSig; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); // if Property is already marked, just return if (m_pMiniMd->GetFilterTable()->IsPropertyMarked(pr)) goto ErrExit; IfFailGo( m_pMiniMd->GetFilterTable()->MarkProperty( pr ) ); // marking the backing field, event changing and event changed IfFailGo(m_pMiniMd->GetPropertyRecord(RidFromToken(pr), &pRec)); // Walk the signature and mark all of the embedded types IfFailGo(m_pMiniMd->getTypeOfProperty(pRec, &pbSig, &cbSize)); IfFailGo( MarkSignature(pbSig, cbSize, &cbUsed) ); // Note that we don't need to mark the MethodSemantics. Because the association of MethodSemantics // is marked. The Method column can only store MethodDef, ie the MethodDef has the same parent as // this Property. IfFailGo( MarkCustomAttributesWithParentToken(pr) ); // IfFailGo( MarkDeclSecuritiesWithParentToken(pr) ); ErrExit: return hr; } // HRESULT FilterManager::MarkProperty()
//***************************************************************************** // cascading Mark of an event token //***************************************************************************** HRESULT FilterManager::MarkEvent(mdEvent ev) { HRESULT hr = NOERROR; EventRec *pRec; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); // if Event is already marked, just return if (m_pMiniMd->GetFilterTable()->IsEventMarked(ev)) goto ErrExit; IfFailGo( m_pMiniMd->GetFilterTable()->MarkEvent( ev ) ); // mark the event type as well IfFailGo(m_pMiniMd->GetEventRecord(RidFromToken(ev), &pRec)); IfFailGo( Mark(m_pMiniMd->getEventTypeOfEvent(pRec)) ); // Note that we don't need to mark the MethodSemantics. Because the association of MethodSemantics // is marked. The Method column can only store MethodDef, ie the MethodDef has the same parent as // this Event. IfFailGo( MarkCustomAttributesWithParentToken(ev) ); // IfFailGo( MarkDeclSecuritiesWithParentToken(ev) ); ErrExit: return hr; } // HRESULT FilterManager::MarkEvent()
/*************************************************************************** * Store from top of the stack to a static field ***************************************************************************/ void CCilVm::storeStaticField( const RID rid ) { assert( TypeFromToken( rid ) == MDT_FIELDDEF ); uint32_t iIndex = RidFromToken( rid ); if( m_pStaticFieldTable[ iIndex ].getFlag() & OPERAND_FLAG_READONLY ) { //Read only variable popEvalStack(); return; } if( m_pStaticFieldTable[ iIndex ].getFlag() & OPERAND_FLAG_STRICT ) { //Test type constraint storeAsRestrictedType( m_pStaticFieldTable[ iIndex ] ); popEvalStack(); return; } getEvalStackFirstEntry().moveTo( m_pStaticFieldTable[ iIndex ] ); popEvalStackFast(); }
//***************************************************************************** // cascading Mark of a TypeSpec //***************************************************************************** HRESULT FilterManager::MarkTypeSpec(mdTypeSpec ts) { HRESULT hr = NOERROR; TypeSpecRec *pRec; ULONG cbSize; ULONG cbUsed; PCCOR_SIGNATURE pbSig; IHostFilter *pFilter = m_pMiniMd->GetHostFilter(); // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); // if TypeRef is already marked, just return if (m_pMiniMd->GetFilterTable()->IsTypeSpecMarked(ts)) goto ErrExit; // To mark the TypeSpec, we will need to mark // all of the embedded TypeRef or TypeDef // IfFailGo( m_pMiniMd->GetFilterTable()->MarkTypeSpec( ts ) ); if (pFilter) pFilter->MarkToken(ts); // Walk the signature and mark all of the embedded types IfFailGo(m_pMiniMd->GetTypeSpecRecord(RidFromToken(ts), &pRec)); IfFailGo(m_pMiniMd->getSignatureOfTypeSpec(pRec, &pbSig, &cbSize)); IfFailGo( MarkFieldSignature(pbSig, cbSize, &cbUsed) ); IfFailGo( MarkCustomAttributesWithParentToken(ts) ); ErrExit: return hr; } // HRESULT FilterManager::MarkTypeSpec()
//******************************************************************************* // Helper: Set the specified attributes on the given ManifestResource token. //******************************************************************************* HRESULT RegMeta::_SetManifestResourceProps(// S_OK or error. mdManifestResource mr, // [IN] ManifestResource token. mdToken tkImplementation, // [IN] mdFile or mdAssemblyRef that provides the resource. DWORD dwOffset, // [IN] Offset to the beginning of the resource within the file. DWORD dwResourceFlags) // [IN] Flags. { ManifestResourceRec *pRecord = NULL; HRESULT hr = S_OK; IfFailGo(m_pStgdb->m_MiniMd.GetManifestResourceRecord(RidFromToken(mr), &pRecord)); // Set the attributes. if (tkImplementation != mdTokenNil) IfFailGo(m_pStgdb->m_MiniMd.PutToken(TBL_ManifestResource, ManifestResourceRec::COL_Implementation, pRecord, tkImplementation)); if (dwOffset != ULONG_MAX) pRecord->SetOffset(dwOffset); if (dwResourceFlags != ULONG_MAX) pRecord->SetFlags(dwResourceFlags); IfFailGo(UpdateENCLog(mr)); ErrExit: return hr; } // RegMeta::_SetManifestResourceProps
//******************************************************************************* // Helper: Set the specified attributes on the given ExportedType token. //******************************************************************************* HRESULT RegMeta::_SetExportedTypeProps( // S_OK or error. mdExportedType ct, // [IN] ExportedType token. mdToken tkImplementation, // [IN] mdFile or mdAssemblyRef that provides the ExportedType. mdTypeDef tkTypeDef, // [IN] TypeDef token within the file. DWORD dwExportedTypeFlags) // [IN] Flags. { ExportedTypeRec *pRecord; HRESULT hr = S_OK; IfFailGo(m_pStgdb->m_MiniMd.GetExportedTypeRecord(RidFromToken(ct), &pRecord)); if(! IsNilToken(tkImplementation)) IfFailGo(m_pStgdb->m_MiniMd.PutToken(TBL_ExportedType, ExportedTypeRec::COL_Implementation, pRecord, tkImplementation)); if (! IsNilToken(tkTypeDef)) { _ASSERTE(TypeFromToken(tkTypeDef) == mdtTypeDef); pRecord->SetTypeDefId(tkTypeDef); } if (dwExportedTypeFlags != ULONG_MAX) pRecord->SetFlags(dwExportedTypeFlags); IfFailGo(UpdateENCLog(ct)); ErrExit: return hr; } // RegMeta::_SetExportedTypeProps
//******************************************************************************* // Set the specified attributes on the given File token. //******************************************************************************* STDMETHODIMP RegMeta::SetFileProps( // S_OK or error. mdFile file, // [IN] File token. const void *pbHashValue, // [IN] Hash Blob. ULONG cbHashValue, // [IN] Count of bytes in the Hash Blob. DWORD dwFileFlags) // [IN] Flags. { HRESULT hr = S_OK; BEGIN_ENTRYPOINT_NOTHROW; _ASSERTE(TypeFromToken(file) == mdtFile && RidFromToken(file)); LOG((LOGMD, "RegMeta::SetFileProps(%#08x, %#08x, %#08x, %#08x)\n", file, pbHashValue, cbHashValue, dwFileFlags)); START_MD_PERF(); LOCKWRITE(); IfFailGo(m_pStgdb->m_MiniMd.PreUpdate()); IfFailGo( _SetFileProps(file, pbHashValue, cbHashValue, dwFileFlags) ); ErrExit: STOP_MD_PERF(SetFileProps); END_ENTRYPOINT_NOTHROW; return hr; } // RegMeta::SetFileProps
/*************************************************************************** * Set Field Value (Debugger helper) ***************************************************************************/ bool CCilVm::setStaticField( const RID rid, const CVariable& value ) { assert( TypeFromToken( rid ) == MDT_FIELDDEF ); uint32_t iIndex = RidFromToken( rid ); m_pStaticFieldTable[ iIndex ] = value; return true; }
//***************************************************************************** // cascading Mark of a MethodSpec //***************************************************************************** HRESULT FilterManager::MarkMethodSpec(mdMethodSpec ms) { HRESULT hr = NOERROR; MethodSpecRec *pRec; ULONG cbSize; ULONG cbUsed; PCCOR_SIGNATURE pbSig; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); // if MethodSpec is already marked, just return if (m_pMiniMd->GetFilterTable()->IsMethodSpecMarked(ms)) goto ErrExit; IfFailGo( m_pMiniMd->GetFilterTable()->MarkMethodSpec( ms ) ); // Mark MethodRef or MethodDef and embedded TypeRef and TypeDef tokens IfFailGo(m_pMiniMd->GetMethodSpecRecord(RidFromToken(ms), &pRec)); IfFailGo( Mark(m_pMiniMd->getMethodOfMethodSpec(pRec)) ); IfFailGo(m_pMiniMd->getInstantiationOfMethodSpec(pRec, &pbSig, &cbSize)); IfFailGo( MarkSignature(pbSig, cbSize, &cbUsed) ); ErrExit: return hr; } // HRESULT FilterManager::MarkMethodSpec()
//***************************************************************************** // cascading Mark of a field token //***************************************************************************** HRESULT FilterManager::MarkField(mdFieldDef fd) { HRESULT hr = NOERROR; FieldRec *pRec; ULONG cbSize; ULONG cbUsed; PCCOR_SIGNATURE pbSig; IHostFilter *pFilter = m_pMiniMd->GetHostFilter(); // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); // if FieldDef is already marked, just return if (m_pMiniMd->GetFilterTable()->IsFieldMarked(fd)) goto ErrExit; IfFailGo( m_pMiniMd->GetFilterTable()->MarkField( fd ) ); if (pFilter) pFilter->MarkToken(fd); // We should not mark all of the MemberRef with the parent of this FieldDef token. // Because not all of the call sites are needed. // // Walk the signature and mark all of the embedded types IfFailGo(m_pMiniMd->GetFieldRecord(RidFromToken(fd), &pRec)); IfFailGo(m_pMiniMd->getSignatureOfField(pRec, &pbSig, &cbSize)); IfFailGo( MarkSignature(pbSig, cbSize, &cbUsed) ); IfFailGo( MarkCustomAttributesWithParentToken(fd) ); // IfFailGo( MarkDeclSecuritiesWithParentToken(fd) ); ErrExit: return hr; } // HRESULT FilterManager::MarkField()
/*************************************************************************** * get Field Value (Debugger helper) ***************************************************************************/ CVariable& CCilVm::getStaticField( const RID rid ) { assert( TypeFromToken( rid ) == MDT_FIELDDEF ); uint32_t iIndex = RidFromToken( rid ); assert( iIndex < m_iStaticFieldTalbeSize ); return m_pStaticFieldTable[ iIndex ]; }
// Find MSCORLIB CAssemblyFile *CAsmLink::GetStdLib() { if (m_pStdLib) return m_pStdLib; // First search imports DWORD i, count; CFile *file = NULL; HRESULT hr; for (i = 0, count = m_pImports->CountFiles(); i < count; i++) { hr = m_pImports->GetFile(i, &file); if (FAILED(hr)) break; if (file && file->IsStdLib()) return (m_pStdLib = (CAssemblyFile*)file); } CComPtr<IMetaDataAssemblyImport> pAImport; WCHAR szFilename[MAX_PATH + MAX_PATH]; mdFile tkFile = mdTokenNil; if (FAILED(m_pDisp->GetCORSystemDirectory(szFilename, lengthof(szFilename) - 12, &count))) return NULL; wcscpy(szFilename + count - 1, L"mscorlib.dll"); if (FAILED(ImportFile( szFilename, NULL, FALSE, &tkFile, &pAImport, NULL)) || !pAImport) return NULL; ASSERT(TypeFromToken(tkFile) == mdtAssemblyRef); if (FAILED(m_pImports->GetFile(RidFromToken(tkFile), &file))) return NULL; if (file && file->IsStdLib()) return (m_pStdLib = (CAssemblyFile*)file); return NULL; }
//******************************************************************************* // Set the specified attributes on the given Assembly token. //******************************************************************************* STDMETHODIMP RegMeta::SetAssemblyProps( // S_OK or error. mdAssembly ma, // [IN] Assembly token. const void *pbPublicKey, // [IN] Public key of the assembly. ULONG cbPublicKey, // [IN] Count of bytes in the public key. ULONG ulHashAlgId, // [IN] Hash Algorithm. LPCWSTR szName, // [IN] Name of the assembly. const ASSEMBLYMETADATA *pMetaData, // [IN] Assembly MetaData. DWORD dwAssemblyFlags) // [IN] Flags. { HRESULT hr = S_OK; BEGIN_ENTRYPOINT_NOTHROW; _ASSERTE(TypeFromToken(ma) == mdtAssembly && RidFromToken(ma)); LOG((LOGMD, "RegMeta::SetAssemblyProps(%#08x, %#08x, %#08x, %#08x %S, %#08x, %#08x)\n", ma, pbPublicKey, cbPublicKey, ulHashAlgId, MDSTR(szName), pMetaData, dwAssemblyFlags)); START_MD_PERF(); LOCKWRITE(); IfFailGo(m_pStgdb->m_MiniMd.PreUpdate()); IfFailGo(_SetAssemblyProps(ma, pbPublicKey, cbPublicKey, ulHashAlgId, szName, pMetaData, dwAssemblyFlags)); ErrExit: STOP_MD_PERF(SetAssemblyProps); END_ENTRYPOINT_NOTHROW; return hr; } // STDMETHODIMP SetAssemblyProps()
HRESULT CAsmLink::EmitAssemblyCustomAttribute(mdAssembly AssemblyID, mdToken FileToken, mdToken tkType, void const* pCustomValue, DWORD cbCustomValue, BOOL bSecurity, BOOL bAllowMultiple) { ASSERT(m_bInited && !m_bPreClosed && !m_bManifestEmitted); ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1) || AssemblyID == AssemblyIsUBM); ASSERT((RidFromToken(FileToken) < m_pAssem->CountFiles() && TypeFromToken(FileToken) == mdtFile) || (FileToken == AssemblyID)); HRESULT hr = S_OK; if (AssemblyID == AssemblyIsUBM) { CFile *file = NULL; if (FAILED(hr = m_pAssem->GetFile(FileToken, &file))) return hr; hr = file->AddCustomAttribute(tkType, pCustomValue, cbCustomValue, bSecurity, bAllowMultiple, NULL); } else if (FileToken == AssemblyID) { hr = m_pAssem->AddCustomAttribute(tkType, pCustomValue, cbCustomValue, bSecurity, bAllowMultiple, NULL); } else { // An assembly level custom attribute that is in the wrong scope CFile *file = NULL; if (FAILED(hr = m_pAssem->GetFile(FileToken, &file))) return hr; hr = m_pAssem->AddCustomAttribute(tkType, pCustomValue, cbCustomValue, bSecurity, bAllowMultiple, file); } return hr; }
HRESULT AssemblySpec::InitializeSpec(mdToken kAssemblyRef, IMDInternalImport *pImport, Assembly* pAssembly) { HRESULT hr = S_OK; m_fParsed = TRUE; DWORD rid = RidFromToken(kAssemblyRef); if((rid == 0)||(rid > pImport->GetCountWithTokenKind(mdtAssemblyRef))) { BAD_FORMAT_ASSERT(!"AssemblyRef Token Out of Range"); return COR_E_BADIMAGEFORMAT; } // Hash algorithm used to find this hash is saved in Assembly def pImport->GetAssemblyRefProps(kAssemblyRef, // [IN] The AssemblyRef for which to get the properties. (const void**) &m_pbPublicKeyOrToken, // [OUT] Pointer to the public key or token. &m_cbPublicKeyOrToken, // [OUT] Count of bytes in the public key or token. &m_pAssemblyName, // [OUT] Buffer to fill with name. &m_context, // [OUT] Assembly MetaData. NULL, // [OUT] Hash blob. NULL, // [OUT] Count of bytes in the hash blob. &m_dwFlags); // [OUT] Flags. if ((!m_pAssemblyName) || (*m_pAssemblyName == 0)) { BAD_FORMAT_ASSERT(!"NULL AssemblyRef Name"); return COR_E_BADIMAGEFORMAT; } MAKE_WIDEPTR_FROMUTF8(pwName,m_pAssemblyName); if (wcschr(pwName,'\\') || wcschr(pwName,'/') || wcschr(pwName,':') || (RunningOnWin95() && ContainsUnmappableANSIChars(pwName))) { BAD_FORMAT_ASSERT(!"Bad AssemblyRef Name"); return COR_E_BADIMAGEFORMAT; } if((!m_pbPublicKeyOrToken) && (m_cbPublicKeyOrToken != 0)) { BAD_FORMAT_ASSERT(!"NULL Public Key or Token of AssemblyRef"); return COR_E_BADIMAGEFORMAT; } // Let's get the CodeBase from the caller and use it as a hint if(pAssembly && (!pAssembly->IsShared())) m_CodeInfo.SetParentAssembly(pAssembly->GetFusionAssembly()); #if defined(_DEBUG) && defined(FUSION_SUPPORTED) { // Test fusion conversion IAssemblyName *pFusionName; _ASSERTE(CreateFusionName(&pFusionName, TRUE) == S_OK); AssemblySpec testFusion; _ASSERTE(testFusion.InitializeSpec(pFusionName) == S_OK); pFusionName->Release(); } #endif // _DEBUG && FUSION_SUPPORTED return hr; }
HRESULT CAsmLink::ExportType(mdAssembly AssemblyID, mdToken FileToken, mdTypeDef TypeToken, LPCWSTR pszTypename, DWORD dwFlags, mdExportedType* pType) { ASSERT(m_bInited && !m_bPreClosed); ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1) || AssemblyID == AssemblyIsUBM); ASSERT(AssemblyID == FileToken || (RidFromToken(FileToken) < m_pAssem->CountFiles() && TypeFromToken(FileToken) == mdtFile)); if (AssemblyID == AssemblyIsUBM || FileToken == AssemblyID) return S_FALSE; HRESULT hr; CFile *file = NULL; if (FAILED(hr = m_pAssem->GetFile(RidFromToken(FileToken), &file))) return hr; return m_pAssem->AddExportType( file->GetFileToken(), TypeToken, pszTypename, dwFlags, pType); }
//***************************************************************************** // cascading Mark of an TypeDef token //***************************************************************************** HRESULT FilterManager::MarkTypeDef( mdTypeDef td) { HRESULT hr = NOERROR; TypeDefRec *pRec; IHostFilter *pFilter = m_pMiniMd->GetHostFilter(); DWORD dwFlags; RID iNester; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); // if TypeDef is already marked, just return if (m_pMiniMd->GetFilterTable()->IsTypeDefMarked(td)) goto ErrExit; // Mark the TypeDef first to avoid duplicate marking IfFailGo( m_pMiniMd->GetFilterTable()->MarkTypeDef(td) ); if (pFilter) pFilter->MarkToken(td); // We don't need to mark InterfaceImpl but we need to mark the // TypeDef/TypeRef associated with InterfaceImpl. IfFailGo( MarkInterfaceImpls(td) ); // mark the base class IfFailGo(m_pMiniMd->GetTypeDefRecord(RidFromToken(td), &pRec)); IfFailGo( Mark(m_pMiniMd->getExtendsOfTypeDef(pRec)) ); // mark all of the children of this TypeDef IfFailGo( MarkMethodsWithParentToken(td) ); IfFailGo( MarkMethodImplsWithParentToken(td) ); IfFailGo( MarkFieldsWithParentToken(td) ); IfFailGo( MarkEventsWithParentToken(td) ); IfFailGo( MarkPropertiesWithParentToken(td) ); // mark any GenericParam of this TypeDef IfFailGo( MarkGenericParamWithParentToken(td) ); // mark custom value and permission IfFailGo( MarkCustomAttributesWithParentToken(td) ); IfFailGo( MarkDeclSecuritiesWithParentToken(td) ); // If the class is a Nested class mark the parent, recursively. dwFlags = m_pMiniMd->getFlagsOfTypeDef(pRec); if (IsTdNested(dwFlags)) { NestedClassRec *pNestClassRec; IfFailGo(m_pMiniMd->FindNestedClassHelper(td, &iNester)); if (InvalidRid(iNester)) IfFailGo(CLDB_E_RECORD_NOTFOUND); IfFailGo(m_pMiniMd->GetNestedClassRecord(iNester, &pNestClassRec)); IfFailGo(MarkTypeDef(m_pMiniMd->getEnclosingClassOfNestedClass(pNestClassRec))); } ErrExit: return hr; } // HRESULT FilterManager::MarkTypeDef()
INT32 QCALLTYPE COMDynamicWrite::DefineType(QCall::ModuleHandle pModule, LPCWSTR wszFullName, INT32 tkParent, INT32 attributes, INT32 tkEnclosingType, INT32 * pInterfaceTokens) { QCALL_CONTRACT; mdTypeDef classE = mdTokenNil; BEGIN_QCALL; RefClassWriter * pRCW = pModule->GetReflectionModule()->GetClassWriter(); _ASSERTE(pRCW); HRESULT hr; if (RidFromToken(tkEnclosingType)) { // defining nested type hr = pRCW->GetEmitter()->DefineNestedType(wszFullName, attributes, tkParent == 0 ? mdTypeRefNil : tkParent, (mdToken *)pInterfaceTokens, tkEnclosingType, &classE); } else { // top level type hr = pRCW->GetEmitter()->DefineTypeDef(wszFullName, attributes, tkParent == 0 ? mdTypeRefNil : tkParent, (mdToken *)pInterfaceTokens, &classE); } if (hr == META_S_DUPLICATE) { COMPlusThrow(kArgumentException, W("Argument_DuplicateTypeName")); } if (FAILED(hr)) { _ASSERTE(hr == E_OUTOFMEMORY || !"DefineTypeDef Failed"); COMPlusThrowHR(hr); } AllocMemTracker amTracker; pModule->GetClassLoader()->AddAvailableClassDontHaveLock(pModule, classE, &amTracker); amTracker.SuppressRelease(); END_QCALL; return (INT32)classE; }
//***************************************************************************** // cascading Mark of a TypeRef //***************************************************************************** HRESULT FilterManager::MarkTypeRef(mdTypeRef tr) { HRESULT hr = NOERROR; TOKENMAP *tkMap; mdTypeDef td; IHostFilter *pFilter = m_pMiniMd->GetHostFilter(); TypeRefRec *pRec; mdToken parentTk; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); // if TypeRef is already marked, just return if (m_pMiniMd->GetFilterTable()->IsTypeRefMarked(tr)) goto ErrExit; IfFailGo( m_pMiniMd->GetFilterTable()->MarkTypeRef( tr ) ); if (pFilter) pFilter->MarkToken(tr); IfFailGo(m_pMiniMd->GetTypeRefRecord(RidFromToken(tr), &pRec)); parentTk = m_pMiniMd->getResolutionScopeOfTypeRef(pRec); if ( RidFromToken(parentTk) ) { IfFailGo( Mark( parentTk ) ); } tkMap = m_pMiniMd->GetTypeRefToTypeDefMap(); PREFIX_ASSUME(tkMap != NULL); td = *(tkMap->Get(RidFromToken(tr))); if ( td != mdTokenNil ) { // TypeRef is referring to a TypeDef within the same module. // Mark the TypeDef as well. // IfFailGo( Mark(td) ); } IfFailGo( MarkCustomAttributesWithParentToken(tr) ); ErrExit: return hr; } // HRESULT FilterManager::MarkTypeRef()
//***************************************************************************** // Called by the meta data engine when a token is remapped to a new location. // This value is recorded in the m_rgMap array based on type and rid of the // from token value. //***************************************************************************** HRESULT STDMETHODCALLTYPE CeeGenTokenMapper::Map( mdToken tkFrom, mdToken tkTo) { HRESULT hr = S_OK; mdToken *pToken = NULL; ULONG ridFrom = 0; TOKENMAP *pMap = NULL; BEGIN_ENTRYPOINT_NOTHROW; if ( IndexForType(tkFrom) == -1 ) { // It is a type that we are not tracking, such as mdtProperty or mdtEvent, // just return S_OK. goto ErrExit; } _ASSERTE(IndexForType(tkFrom) < GetMaxMapSize()); _ASSERTE(IndexForType(tkTo) != -1 && IndexForType(tkTo) < GetMaxMapSize()); // If there is another token mapper that the user wants called, go // ahead and call it now. if (m_pIMapToken) m_pIMapToken->Map(tkFrom, tkTo); ridFrom = RidFromToken(tkFrom); pMap = &m_rgMap[IndexForType(tkFrom)]; // If there isn't enough entries, fill out array up to the count // and mark the token to nil so we know there is no valid data yet. if ((ULONG) pMap->Count() <= ridFrom) { for (int i=ridFrom - pMap->Count() + 1; i; i--) { pToken = pMap->Append(); if (!pToken) break; *pToken = mdTokenNil; } _ASSERTE(!pToken || pMap->Get(ridFrom) == pToken); } else pToken = pMap->Get(ridFrom); IfNullGo(pToken); *pToken = tkTo; ErrExit: END_ENTRYPOINT_NOTHROW; return hr; }
HRESULT CAsmLink::GetResolutionScope(mdAssembly AssemblyID, mdToken FileToken, mdToken TargetFile, mdToken* pScope) { ASSERT(m_bInited && !m_bPreClosed && m_pAssem); ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1) || AssemblyID == AssemblyIsUBM); ASSERT((RidFromToken(FileToken) < m_pAssem->CountFiles() && TypeFromToken(FileToken) == mdtFile) || (FileToken == AssemblyID)); ASSERT(pScope != NULL); if (FileToken == TargetFile) { *pScope = TokenFromRid(1, mdtModule); return S_OK; } HRESULT hr = S_OK; CFile *file = NULL; if (FileToken == AssemblyID) { file = m_pAssem; } else { if (FAILED(hr = m_pAssem->GetFile(FileToken, &file))) return hr; } if (TypeFromToken(TargetFile) == mdtFile) { // make a moduleref to target file in "file" CFile *target; if (FAILED(hr = m_pAssem->GetFile(TargetFile, &target))) return hr; hr = target->MakeModuleRef(file->GetEmitScope(), pScope); } else if (TypeFromToken(TargetFile) == mdtModule) { // make a moduleref to target file in "file" CFile *target; if (FAILED(hr = m_pModules->GetFile(TargetFile, &target))) return hr; hr = target->MakeModuleRef(file->GetEmitScope(), pScope); } else if (TypeFromToken(TargetFile) == mdtAssembly) { ASSERT(TargetFile != AssemblyIsUBM); // make a moduleref to the manifest file in "file" hr = m_pAssem->MakeModuleRef(file->GetEmitScope(), pScope); } else if (TypeFromToken(TargetFile) == mdtAssemblyRef) { // make an assembly ref in "file" CFile *target; if (FAILED(hr = m_pImports->GetFile(TargetFile, &target))) return hr; if (file == m_pAssem) // Special Case this so we don't have to re-QI for the AssemblyEmit interface hr = ((CAssemblyFile*)target)->MakeAssemblyRef(m_pAssem->GetEmitter(), pScope); else hr = ((CAssemblyFile*)target)->MakeAssemblyRef(file->GetEmitScope(), pScope); } else hr = E_INVALIDARG; return hr; }
HRESULT CAsmLink::ExportNestedType(mdAssembly AssemblyID, mdToken FileToken, mdTypeDef TypeToken, mdExportedType ParentType, LPCWSTR pszTypename, DWORD dwFlags, mdExportedType* pType) { ASSERT(m_bInited && !m_bPreClosed); ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1) || AssemblyID == AssemblyIsUBM); ASSERT(AssemblyID == FileToken || (RidFromToken(FileToken) < m_pAssem->CountFiles() && TypeFromToken(FileToken) == mdtFile)); ASSERT(IsTdNested(dwFlags)); if (AssemblyID == AssemblyIsUBM || FileToken == AssemblyID) return S_FALSE; return m_pAssem->AddExportType( ParentType, TypeToken, pszTypename, dwFlags, pType); }