//***************************************************************************** // Remove a RegMeta pointer from the loaded module list //***************************************************************************** HRESULT LOADEDMODULES::ResolveTypeRefWithLoadedModules( mdTypeRef tr, // [IN] TypeRef to be resolved. IMetaModelCommon *pCommon, // [IN] scope in which the typeref is defined. REFIID riid, // [IN] iid for the return interface IUnknown **ppIScope, // [OUT] return interface mdTypeDef *ptd) // [OUT] typedef corresponding the typeref { HRESULT hr = NOERROR; RegMeta *pRegMeta; CQuickArray<mdTypeRef> cqaNesters; CQuickArray<LPCUTF8> cqaNesterNamespaces; CQuickArray<LPCUTF8> cqaNesterNames; int count; int index; if (g_LoadedModules == NULL) { // No loaded module! _ASSERTE(!"Bad state!"); return E_FAIL; } LOCKREAD(); // Get the Nesting hierarchy. IfFailGo(ImportHelper::GetNesterHierarchy(pCommon, tr, cqaNesters, cqaNesterNamespaces, cqaNesterNames)); count = g_LoadedModules->Count(); for (index = 0; index < count; index++) { pRegMeta = (*g_LoadedModules)[index]; hr = ImportHelper::FindNestedTypeDef( pRegMeta->GetMiniMd(), cqaNesterNamespaces, cqaNesterNames, mdTokenNil, ptd); if (SUCCEEDED(hr)) { // found a loaded module containing the TypeDef. hr = pRegMeta->QueryInterface(riid, (void **)ppIScope); break; } else if (hr != CLDB_E_RECORD_NOTFOUND) IfFailGo(hr); } if (FAILED(hr)) { // cannot find the match! hr = E_FAIL; } ErrExit: return hr; } // LOADEDMODULES::ResolveTypeRefWithLoadedModules
//************************************************************* // // Open the file with anme wzModule and check to see if there is a type // with namespace/class of wzNamespace/wzType. If so, return the RegMeta // corresponding to the file and the mdTypeDef of the typedef // //************************************************************* HRESULT CORPATHService::FindTypeDef( __in __in_z LPWSTR wzModule, // name of the module that we are going to open mdTypeRef tr, // TypeRef to resolve. IMetaModelCommon * pCommon, // Scope in which the TypeRef is defined. REFIID riid, IUnknown ** ppIScope, mdTypeDef * ptd) // [OUT] the type that we resolve to { HRESULT hr = NOERROR; NewHolder<Disp> pDisp; ReleaseHolder<IMetaDataImport2> pImport = NULL; CQuickArray<mdTypeRef> cqaNesters; CQuickArray<LPCUTF8> cqaNesterNamespaces; CQuickArray<LPCUTF8> cqaNesterNames; RegMeta * pRegMeta; _ASSERTE((ppIScope != NULL) && (ptd != NULL)); *ppIScope = NULL; pDisp = new (nothrow) Disp; IfNullGo(pDisp); IfFailGo(pDisp->OpenScope(wzModule, 0, IID_IMetaDataImport2, (IUnknown **)&pImport)); pRegMeta = static_cast<RegMeta *>(pImport.GetValue()); // Get the Nesting hierarchy. IfFailGo(ImportHelper::GetNesterHierarchy(pCommon, tr, cqaNesters, cqaNesterNamespaces, cqaNesterNames)); hr = ImportHelper::FindNestedTypeDef( pRegMeta->GetMiniMd(), cqaNesterNamespaces, cqaNesterNames, mdTokenNil, ptd); if (SUCCEEDED(hr)) { *ppIScope = pImport.Extract(); } ErrExit: return hr; } // CORPATHService::FindTypeDef
//***************************************************************************** // This function returns the requested public interface based on the given // internal import interface. // A common path to call this is updating the matedata for dynamic modules. //***************************************************************************** STDAPI MDReOpenMetaDataWithMemoryEx( void *pImport, // [IN] Given scope. public interfaces LPCVOID pData, // [in] Location of scope data. ULONG cbData, // [in] Size of the data pointed to by pData. DWORD dwReOpenFlags) // [in] Flags for ReOpen { HRESULT hr = S_OK; IUnknown *pUnk = (IUnknown *) pImport; IMetaDataImport2 *pMDImport = NULL; RegMeta *pRegMeta = NULL; _ASSERTE(pImport); IfFailGo( pUnk->QueryInterface(IID_IMetaDataImport2, (void **) &pMDImport) ); pRegMeta = (RegMeta*) pMDImport; IfFailGo( pRegMeta->ReOpenWithMemory(pData, cbData, dwReOpenFlags) ); ErrExit: if (pMDImport) pMDImport->Release(); return hr; } // MDReOpenMetaDataWithMemoryEx
void initSets() { m.clear(); for(auto i : instructions) { auto t = meta(i); m.used.insert(t.used.begin(),t.used.end()); m.dead.insert(t.dead.begin(),t.dead.end()); } if(branchOn) m.used.insert(branchOn); vector<int> t; set_difference( m.used.begin(), m.used.end(), m.dead.begin(), m.dead.end(), std::back_inserter(t)); m.alive = set<int>(t.begin(), t.end()); }
//***************************************************************************** // Remove a RegMeta pointer from the loaded module list //***************************************************************************** // static HRESULT LOADEDMODULES::ResolveTypeRefWithLoadedModules( mdTypeRef tkTypeRef, // [IN] TypeRef to be resolved. RegMeta * pTypeRefRegMeta, // [IN] Scope in which the TypeRef is defined. IMetaModelCommon * pTypeRefScope, // [IN] Scope in which the TypeRef is defined. REFIID riid, // [IN] iid for the return interface. IUnknown ** ppIScope, // [OUT] Return interface. mdTypeDef * ptd) // [OUT] TypeDef corresponding the TypeRef. { HRESULT hr = NOERROR; RegMeta * pRegMeta; CQuickArray<mdTypeRef> cqaNesters; CQuickArray<LPCUTF8> cqaNesterNamespaces; CQuickArray<LPCUTF8> cqaNesterNames; IfFailGo(InitializeStatics()); { LOCKREAD(); // Get the Nesting hierarchy. IfFailGo(ImportHelper::GetNesterHierarchy( pTypeRefScope, tkTypeRef, cqaNesters, cqaNesterNamespaces, cqaNesterNames)); int count = s_pLoadedModules->Count(); for (int index = 0; index < count; index++) { pRegMeta = (*s_pLoadedModules)[index]; { // Do not lock the TypeRef RegMeta (again), as it is already locked for read by the caller. // The code:UTSemReadWrite will block ReadLock even for thread holding already the read lock if // some other thread is waiting for WriteLock on the same lock. That would cause dead-lock if we // try to lock for read again here. CMDSemReadWrite cSemRegMeta((pRegMeta == pTypeRefRegMeta) ? NULL : pRegMeta->GetReaderWriterLock()); IfFailGo(cSemRegMeta.LockRead()); hr = ImportHelper::FindNestedTypeDef( pRegMeta->GetMiniMd(), cqaNesterNamespaces, cqaNesterNames, mdTokenNil, ptd); } if (hr == CLDB_E_RECORD_NOTFOUND) { // Process next MetaData module continue; } IfFailGo(hr); // Found a loaded module containing the TypeDef. IfFailGo(pRegMeta->QueryInterface(riid, (void **)ppIScope)); break; } } if (FAILED(hr)) { // cannot find the match! hr = E_FAIL; } ErrExit: return hr; } // LOADEDMODULES::ResolveTypeRefWithLoadedModules
//***************************************************************************** // Search the cached RegMetas for a given scope. //***************************************************************************** HRESULT LOADEDMODULES::FindCachedReadOnlyEntry( LPCWSTR szName, // Name of the desired file. DWORD dwOpenFlags, // Flags the new file is opened with. RegMeta ** ppMeta) // Put found RegMeta here. { RegMeta * pRegMeta = 0; BOOL bWillBeCopyMemory; // Will the opened file be copied to memory? DWORD dwLowFileSize; // Low bytes of this file's size DWORD dwLowFileTime; // Low butes of this file's last write time HRESULT hr; ULONG ixHash = 0; IfFailGo(InitializeStatics()); { LOCKREAD(); hr = S_FALSE; // We haven't found a match yet. // Avoid confusion. *ppMeta = NULL; bWillBeCopyMemory = IsOfCopyMemory(dwOpenFlags); // The cache is locked for read, so the list will not change. // Figure out the size and timestamp of this file WIN32_FILE_ATTRIBUTE_DATA faData; if (!WszGetFileAttributesEx(szName, GetFileExInfoStandard, &faData)) return E_FAIL; dwLowFileSize = faData.nFileSizeLow; dwLowFileTime = faData.ftLastWriteTime.dwLowDateTime; // Check the hash first. ixHash = HashFileName(szName); if ((pRegMeta = m_HashedModules[ixHash]) != NULL) { _ASSERTE(pRegMeta->IsReadOnly()); // Only match if the IsOfCopyMemory() bit is the same in both. This is because // when ofCopyMemory is set, the file is not locked on disk, and may become stale // in memory. // // Also, only match if the date and size are the same if (pRegMeta->IsCopyMemory() == bWillBeCopyMemory && pRegMeta->GetLowFileTimeOfDBFile() == dwLowFileTime && pRegMeta->GetLowFileSizeOfDBFile() == dwLowFileSize) { // If the name matches... LPCWSTR pszName = pRegMeta->GetNameOfDBFile(); #ifdef FEATURE_CASE_SENSITIVE_FILESYSTEM if (wcscmp(szName, pszName) == 0) #else if (SString::_wcsicmp(szName, pszName) == 0) #endif { ULONG cRefs; // Found it. Add a reference, and return it. *ppMeta = pRegMeta; cRefs = pRegMeta->AddRef(); LOG((LF_METADATA, LL_INFO10, "Disp::OpenScope found cached RegMeta in hash: %#8x, crefs: %d\n", pRegMeta, cRefs)); return S_OK; } } } // Not found in hash; loop through each loaded modules int count = s_pLoadedModules->Count(); for (int index = 0; index < count; index++) { pRegMeta = (*s_pLoadedModules)[index]; // If the module is read-only, and the CopyMemory bit matches, and the date // and size are the same.... if (pRegMeta->IsReadOnly() && pRegMeta->IsCopyMemory() == bWillBeCopyMemory && pRegMeta->GetLowFileTimeOfDBFile() == dwLowFileTime && pRegMeta->GetLowFileSizeOfDBFile() == dwLowFileSize) { // If the name matches... LPCWSTR pszName = pRegMeta->GetNameOfDBFile(); #ifdef FEATURE_CASE_SENSITIVE_FILESYSTEM if (wcscmp(szName, pszName) == 0) #else if (SString::_wcsicmp(szName, pszName) == 0) #endif { ULONG cRefs; // Found it. Add a reference, and return it. *ppMeta = pRegMeta; cRefs = pRegMeta->AddRef(); // Update the hash. m_HashedModules[ixHash] = pRegMeta; LOG((LF_METADATA, LL_INFO10, "Disp::OpenScope found cached RegMeta by search: %#8x, crefs: %d\n", pRegMeta, cRefs)); return S_OK; } } } } ErrExit: // Didn't find it. LOG((LF_METADATA, LL_INFO10, "Disp::OpenScope did not find cached RegMeta\n")); _ASSERTE(hr != S_OK); return hr; } // LOADEDMODULES::FindCachedReadOnlyEntry