Move the loading of the Scope runtime into a separate project so it can be shared by both ScopeAnalyzer and ScopeProgramAnalysis.

This commit is contained in:
Mike Barnett 2017-07-12 20:22:04 -07:00
Родитель 28d0ca89e6
Коммит bc18e912c2
11 изменённых файлов: 190 добавлений и 204 удалений

Просмотреть файл

@ -142,52 +142,8 @@ namespace ScopeAnalyzer
/// </summary>
private void LoadRuntimeTypes(IAssembly assemblyBeingAnalyzed)
{
// Look for Scope types in an assembly named ScopeRuntime.
IAssembly scopeRuntime = null;
var scopeRuntimeNameAsDll = "ScopeRuntime.dll";
// First, look in the directory the assembly being analyzed is located in
string pathToRuntime = Path.Combine(Path.GetDirectoryName(assemblyBeingAnalyzed.Location), scopeRuntimeNameAsDll);
if (File.Exists(pathToRuntime))
{
scopeRuntime = this.Host.LoadUnitFrom(pathToRuntime) as IAssembly;
goto L;
}
pathToRuntime = Path.ChangeExtension(pathToRuntime, ".exe");
if (File.Exists(pathToRuntime))
{
scopeRuntime = this.Host.LoadUnitFrom(pathToRuntime) as IAssembly;
goto L;
}
// Second, look in the parent directory of the direcoty the assembly being analyzed is located in.
pathToRuntime = Path.Combine(Directory.GetParent(Path.GetDirectoryName(pathToRuntime)).FullName, scopeRuntimeNameAsDll);
if (File.Exists(pathToRuntime))
{
scopeRuntime = this.Host.LoadUnitFrom(pathToRuntime) as IAssembly;
goto L;
}
pathToRuntime = Path.ChangeExtension(pathToRuntime, ".exe");
if (File.Exists(pathToRuntime))
{
scopeRuntime = this.Host.LoadUnitFrom(pathToRuntime) as IAssembly;
goto L;
}
// Third, look in the currently directory
pathToRuntime = Path.Combine(Environment.CurrentDirectory, scopeRuntimeNameAsDll);
if (File.Exists(pathToRuntime))
{
scopeRuntime = this.Host.LoadUnitFrom(pathToRuntime) as IAssembly;
goto L;
}
pathToRuntime = Path.ChangeExtension(pathToRuntime, ".exe");
if (File.Exists(pathToRuntime))
{
scopeRuntime = this.Host.LoadUnitFrom(pathToRuntime) as IAssembly;
goto L;
}
L:
if (scopeRuntime == null)
throw new InvalidOperationException("Cannot find runtime types for the assembly: " + assemblyBeingAnalyzed.Name);
var scopeRuntime = RuntimeLoader.RuntimeLoader.LoadScopeRuntime(this.Host);
processorType = UnitHelper.FindType(this.Host.NameTable, scopeRuntime, "ScopeRuntime.Processor");
reducerType = UnitHelper.FindType(this.Host.NameTable, scopeRuntime, "ScopeRuntime.Reducer");

Просмотреть файл

@ -112,6 +112,10 @@
<Project>{45c7b613-e32d-43e8-8030-932d509602eb}</Project>
<Name>Backend</Name>
</ProjectReference>
<ProjectReference Include="..\..\ScopeRuntimeLoader\ScopeRuntimeLoader.csproj">
<Project>{6f190722-b514-4f7e-8b8b-d7fdf6baa106}</Project>
<Name>ScopeRuntimeLoader</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

Просмотреть файл

@ -23,6 +23,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScopeAnalyzer", "ColumnRedu
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScopeRuntime", "ScopeProgramAnalysis\Tests\ScopeRuntime\ScopeRuntime.csproj", "{B82D9314-1EF8-4B8C-9E7A-17597ECED6CF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScopeRuntimeLoader", "ScopeRuntimeLoader\ScopeRuntimeLoader.csproj", "{6F190722-B514-4F7E-8B8B-D7FDF6BAA106}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -65,6 +67,10 @@ Global
{B82D9314-1EF8-4B8C-9E7A-17597ECED6CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B82D9314-1EF8-4B8C-9E7A-17597ECED6CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B82D9314-1EF8-4B8C-9E7A-17597ECED6CF}.Release|Any CPU.Build.0 = Release|Any CPU
{6F190722-B514-4F7E-8B8B-D7FDF6BAA106}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6F190722-B514-4F7E-8B8B-D7FDF6BAA106}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6F190722-B514-4F7E-8B8B-D7FDF6BAA106}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6F190722-B514-4F7E-8B8B-D7FDF6BAA106}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

Просмотреть файл

@ -10,6 +10,7 @@ using Microsoft.Cci;
using ScopeProgramAnalysis.Framework;
using System;
using System.Diagnostics;
using RuntimeLoader;
namespace ScopeProgramAnalysis
{

Просмотреть файл

@ -87,39 +87,6 @@ namespace ScopeProgramAnalysis.Framework
return module.ContainingAssembly;
}
public Tuple<IAssembly,ISourceLocationProvider> LoadAssembly(string fileName)
{
var unit = cciHost.LoadedUnits.SingleOrDefault(u => u.Location == fileName);
if(unit!=null)
{
return Tuple.Create(unit as IAssembly, sourceProviderForAssembly[unit as IAssembly]);
}
var module = cciHost.LoadUnitFrom(fileName) as IModule;
if (module == null || module == Dummy.Module || module == Dummy.Assembly)
throw new Exception(String.Format("The input '{0}' is not a valid CLR module or assembly.", fileName));
var pdbFileName = Path.ChangeExtension(fileName, "pdb");
PdbReader pdbReader = null;
if (File.Exists(pdbFileName))
{
using (var pdbStream = File.OpenRead(pdbFileName))
{
pdbReader = new PdbReader(pdbStream, cciHost);
}
}
sourceProviderForAssembly.Add(module.ContainingAssembly, pdbReader);
if (module.ContainingAssembly.NamespaceRoot.Members.Any(m => m.Name.Value == "ScopeRuntime"))
ScopeTypes.InitializeScopeTypes(cciHost);
return Tuple.Create(module.ContainingAssembly, pdbReader as ISourceLocationProvider);
}
public Tuple<IAssembly, ISourceLocationProvider> LoadMainAssembly(string fileName)
{
if (fileName.StartsWith("file:")) // Is there a better way to tell that it is a Uri?
@ -131,7 +98,7 @@ namespace ScopeProgramAnalysis.Framework
var assemblyParentFolder = Directory.GetParent(assemblyFolder).FullName;
cciHost.AddLibPath(assemblyFolder);
cciHost.AddLibPath(assemblyParentFolder);
this.mainAssemably = this.LoadAssembly(fileName);
this.mainAssemably = RuntimeLoader.RuntimeLoader.LoadAssembly(this.Host, fileName);
return this.mainAssemably;
}
@ -167,7 +134,7 @@ namespace ScopeProgramAnalysis.Framework
{
try
{
return LoadAssembly(path);
return RuntimeLoader.RuntimeLoader.LoadAssembly(this.Host, path);
}
catch (Exception e)
{
@ -181,41 +148,9 @@ namespace ScopeProgramAnalysis.Framework
return null;
}
internal Tuple<IAssembly, ISourceLocationProvider> LoadScopeRuntime(string path)
{
var thisAssembly = System.Reflection.Assembly.GetExecutingAssembly();
var embeddedAssemblyStream = thisAssembly.GetManifestResourceStream("ScopeProgramAnalysis.scoperuntime.exe");
if (!Directory.Exists("MyScopeRuntime"))
{
var d = Directory.CreateDirectory("MyScopeRuntime");
}
var path2 = "MyScopeRuntime\\ScopeRuntime.exe";
if (!File.Exists(path2))
{
using (var fileStream = File.Create(path2))
{
embeddedAssemblyStream.Seek(0, SeekOrigin.Begin);
embeddedAssemblyStream.CopyTo(fileStream);
}
}
var t = LoadAssembly(path2);
return t;
//Tuple<IAssembly, ISourceLocationProvider> t;
//t = TryToLoadAssembly("ScopeRuntime", path);
//if (t == null)
//{
// var currentDirectory = Directory.GetCurrentDirectory();
// t = TryToLoadAssembly("ScopeRuntime", currentDirectory);
//}
//if (t == null)
// throw new InvalidOperationException("Cannot find ScopeRuntime");
//return t;
}
private void LoadRuntimeTypes(string directory)
{
var scopeRuntime = LoadScopeRuntime(directory).Item1;
var scopeRuntime = RuntimeLoader.RuntimeLoader.LoadScopeRuntime(this.Host);
this.runtimeTypes = new RuntimeTypeStruct(this.Host, scopeRuntime);
}
}

Просмотреть файл

@ -2,6 +2,7 @@
using Backend;
using Backend.Utils;
using Microsoft.Cci;
using RuntimeLoader;
namespace ScopeProgramAnalysis.Framework
{

Просмотреть файл

@ -16,6 +16,7 @@ using Backend.ThreeAddressCode.Expressions;
using Backend.ThreeAddressCode.Instructions;
using Backend.Visitors;
using System.Text.RegularExpressions;
using RuntimeLoader;
namespace Backend.Analyses
{

Просмотреть файл

@ -262,6 +262,7 @@ namespace ScopeProgramAnalysis
private static SarifLog AnalyzeDll2(string inputPath, ScopeMethodKind kind, bool useScopeFactory = true, bool interProc = false, StreamWriter outputStream = null)
{
var log = CreateSarifOutput();
log.SchemaUri = new Uri("http://step0");
if (!File.Exists(inputPath))
{
@ -348,10 +349,15 @@ namespace ScopeProgramAnalysis
allSchemas = program.ReadSchemasFromXML2(inputPath);
}
var processorNumber = 0;
foreach (var methodTuple in scopeMethodTuples)
{
processorNumber++;
AnalysisStats.TotalMethods++;
log.SchemaUri = new Uri(log.SchemaUri.ToString() + String.Format("/processor{0}", processorNumber));
var processorClass = methodTuple.Item1;
var entryMethodDef = methodTuple.Item2;
var moveNextMethod = methodTuple.Item3;
@ -370,14 +376,16 @@ namespace ScopeProgramAnalysis
{
continue; // BUG! Silent failure
}
log.SchemaUri = new Uri(log.SchemaUri.ToString() + "/aboutToAnalyze");
Run run;
AnalysisReason errorReason;
var ok = AnalyzeProcessor(inputPath, loader, program.interprocAnalysisManager, program.factoryReducerMap, processorClass, entryMethodDef, moveNextMethod, getEnumMethod, factoryMethod, inputSchema, outputSchema, out run, out errorReason);
if (ok)
{
log.SchemaUri = new Uri(log.SchemaUri.ToString() + "/analyzeOK");
log.Runs.Add(run);
if (outputStream != null)
@ -395,6 +403,8 @@ namespace ScopeProgramAnalysis
}
else
{
log.SchemaUri = new Uri(log.SchemaUri.ToString() + "/analyzeNotOK/" + errorReason.Reason);
Console.WriteLine("Could not analyze {0}", inputPath);
Console.WriteLine("Reason: {0}\n", errorReason.Reason);
@ -664,10 +674,14 @@ namespace ScopeProgramAnalysis
}
catch (Exception e)
{
var body = MethodBodyProvider.Instance.GetBody(moveNextMethod);
errorReason = new AnalysisReason(moveNextMethod, body.Instructions[0],
String.Format(CultureInfo.InvariantCulture, "Thrown exception {0}\n{1}", e.Message, e.StackTrace.ToString()));
return false;
var r = CreateRun(inputPath, "Internal Exception", String.Format(CultureInfo.InvariantCulture, "Thrown exception {0}\n{1}", e.Message, e.StackTrace.ToString()), new List<Result>());
runResult = r;
return true;
//var body = MethodBodyProvider.Instance.GetBody(moveNextMethod);
//errorReason = new AnalysisReason(moveNextMethod, body.Instructions[0],
// String.Format(CultureInfo.InvariantCulture, "Thrown exception {0}\n{1}", e.Message, e.StackTrace.ToString()));
//return false;
}
finally
{
@ -851,7 +865,8 @@ namespace ScopeProgramAnalysis
ret.UsedColumnTime = result.GetProperty<long>("BagOColumnsTime");
}
}
} else
}
else
{
if (run.ToolNotifications.Any())
{
@ -1117,21 +1132,6 @@ namespace ScopeProgramAnalysis
return d;
}
private static void LoadExternalReferences(IEnumerable<string> referenceFiles, MyLoader loader)
{
foreach (var referenceFileName in referenceFiles)
{
try
{
loader.LoadAssembly(referenceFileName);
}
catch (Exception e)
{
AnalysisStats.DllThatFailedToLoad.Add(referenceFileName);
AnalysisStats.TotalDllsFailedToLoad++;
}
}
}
/// <summary>
/// Analyze the ScopeFactory class to get all the Processor/Reducer classes to analyze
/// For each one obtain:

Просмотреть файл

@ -116,9 +116,10 @@
<Project>{90c431c8-ab8c-444f-904c-350c236d27de}</Project>
<Name>ScopeAnalyzer</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="scoperuntime.exe" />
<ProjectReference Include="..\ScopeRuntimeLoader\ScopeRuntimeLoader.csproj">
<Project>{6f190722-b514-4f7e-8b8b-d7fdf6baa106}</Project>
<Name>ScopeRuntimeLoader</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

Просмотреть файл

@ -1,67 +0,0 @@
using System.Collections.Generic;
using Microsoft.Cci;
using System.Linq;
using Backend.Utils;
using ScopeProgramAnalysis.Framework;
namespace ScopeProgramAnalysis
{
public static class ScopeTypes
{
private const string scopeNameSpace = "ScopeRuntime";
private const string scopeAssemblyName = "ScopeRuntime"; // "CodeUnderTest";
private static ICollection<INamedTypeReference> scopeTypes = new List<INamedTypeReference>();
public static INamedTypeReference Producer;
public static INamedTypeReference Processor;
public static INamedTypeReference Reducer;
public static INamedTypeReference Combiner;
public static INamedTypeReference Row;
public static INamedTypeReference RowSet;
public static INamedTypeReference RowList;
public static INamedTypeReference ScopeMap;
public static INamedTypeReference ColumnData;
public static INamedTypeReference ColumnData_Generic;
public static INamedTypeReference Schema;
/// <summary>
/// This is "ugly" but I don't know how to query a type by name
/// Inspired in Zvonimir code
/// </summary>
/// <param name="host"></param>
public static void InitializeScopeTypes(IMetadataHost host)
{
var scopeAssembly = host.LoadedUnits.OfType<IModule>()
.Single(module => module.ContainingAssembly.NamespaceRoot.Members.Any(m => m.Name.Value == "ScopeRuntime"));
foreach (var type in scopeAssembly.GetAllTypes())
{
if (type.FullName() == "ScopeRuntime.Reducer") Reducer = type;
else if (type.FullName() == "ScopeRuntime.Processor") Processor = type;
else if (type.FullName() == "ScopeRuntime.Producer") Producer = type;
else if (type.FullName() == "ScopeRuntime.Row")
{
Row = type;
}
else if (type.FullName() == "ScopeRuntime.RowSet") RowSet = type;
else if (type.FullName() == "ScopeRuntime.RowList") RowList = type;
else if (type.FullName() == "ScopeRuntime.ColumnData") ColumnData = type;
else if (type.FullName() == "ScopeRuntime.ColumnData<T>") ColumnData_Generic = type;
else if (type.FullName() == "ScopeRuntime.Schema") Schema = type;
else if (type.FullName() == "ScopeRuntime.Combiner") Combiner = type;
else if (type.FullName() == "ScopeRuntime.ScopeMap<K, V>") ScopeMap = type;
if (type.ContainingNamespace() == "ScopeRuntime")
scopeTypes.Add(type);
}
}
public static bool Contains(ITypeReference type)
{
if(type is INamedTypeReference)
return scopeTypes.Contains(((INamedTypeReference)type).ResolvedType);
return false;
}
}
}

Просмотреть файл

@ -0,0 +1,148 @@
using Microsoft.Cci;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RuntimeLoader
{
public static class ScopeTypes
{
private const string scopeNameSpace = "ScopeRuntime";
private const string scopeAssemblyName = "ScopeRuntime"; // "CodeUnderTest";
private static ICollection<INamedTypeReference> scopeTypes = new List<INamedTypeReference>();
public static INamedTypeReference Producer;
public static INamedTypeReference Processor;
public static INamedTypeReference Reducer;
public static INamedTypeReference Combiner;
public static INamedTypeReference Row;
public static INamedTypeReference RowSet;
public static INamedTypeReference RowList;
public static INamedTypeReference ScopeMap;
public static INamedTypeReference ColumnData;
public static INamedTypeReference ColumnData_Generic;
public static INamedTypeReference Schema;
/// <summary>
/// This is "ugly" but I don't know how to query a type by name
/// Inspired in Zvonimir code
/// </summary>
/// <param name="host"></param>
public static void InitializeScopeTypes(IMetadataHost host)
{
var scopeAssembly = host.LoadedUnits.OfType<IModule>()
.Single(module => module.ContainingAssembly.NamespaceRoot.Members.Any(m => m.Name.Value == "ScopeRuntime"));
foreach (var type in scopeAssembly.GetAllTypes())
{
if (type.FullName() == "ScopeRuntime.Reducer") Reducer = type;
else if (type.FullName() == "ScopeRuntime.Processor") Processor = type;
else if (type.FullName() == "ScopeRuntime.Producer") Producer = type;
else if (type.FullName() == "ScopeRuntime.Row")
{
Row = type;
}
else if (type.FullName() == "ScopeRuntime.RowSet") RowSet = type;
else if (type.FullName() == "ScopeRuntime.RowList") RowList = type;
else if (type.FullName() == "ScopeRuntime.ColumnData") ColumnData = type;
else if (type.FullName() == "ScopeRuntime.ColumnData<T>") ColumnData_Generic = type;
else if (type.FullName() == "ScopeRuntime.Schema") Schema = type;
else if (type.FullName() == "ScopeRuntime.Combiner") Combiner = type;
else if (type.FullName() == "ScopeRuntime.ScopeMap<K, V>") ScopeMap = type;
if (type.ContainingNamespace() == "ScopeRuntime")
scopeTypes.Add(type);
}
}
public static bool Contains(ITypeReference type)
{
if (type is INamedTypeReference)
return scopeTypes.Contains(((INamedTypeReference)type).ResolvedType);
return false;
}
public static string FullName(this ITypeReference tref)
{
return TypeHelper.GetTypeName(tref, NameFormattingOptions.Signature | NameFormattingOptions.TypeParameters);
}
public static string ContainingNamespace(this ITypeReference type)
{
if (type is INamedTypeDefinition)
return TypeHelper.GetDefiningNamespace((INamedTypeDefinition)type).ToString();
return String.Empty;
}
}
public class RuntimeLoader
{
private static IAssembly cachedScopeRuntime = null;
private static IDictionary<IAssembly, ISourceLocationProvider> sourceProviderForAssembly = new Dictionary<IAssembly, ISourceLocationProvider>();
public static IAssembly LoadScopeRuntime(IMetadataHost host)
{
if (cachedScopeRuntime == null)
{
var thisAssembly = System.Reflection.Assembly.GetExecutingAssembly();
var embeddedAssemblyStream = thisAssembly.GetManifestResourceStream("RuntimeLoader.scoperuntime.exe");
if (!Directory.Exists("MyScopeRuntime"))
{
var d = Directory.CreateDirectory("MyScopeRuntime");
}
var path2 = "MyScopeRuntime\\ScopeRuntime.exe";
if (!File.Exists(path2))
{
using (var fileStream = File.Create(path2))
{
embeddedAssemblyStream.Seek(0, SeekOrigin.Begin);
embeddedAssemblyStream.CopyTo(fileStream);
}
}
var t = LoadAssembly(host, path2);
var scopeRuntime = t.Item1;
ScopeTypes.InitializeScopeTypes(host);
cachedScopeRuntime = scopeRuntime;
}
return cachedScopeRuntime;
}
public static Tuple<IAssembly, ISourceLocationProvider> LoadAssembly(IMetadataHost host, string fileName)
{
var unit = host.LoadedUnits.SingleOrDefault(u => u.Location == fileName);
if (unit != null)
{
return Tuple.Create(unit as IAssembly, sourceProviderForAssembly[unit as IAssembly]);
}
var module = host.LoadUnitFrom(fileName) as IModule;
if (module == null || module == Dummy.Module || module == Dummy.Assembly)
throw new Exception(String.Format("The input '{0}' is not a valid CLR module or assembly.", fileName));
var pdbFileName = Path.ChangeExtension(fileName, "pdb");
PdbReader pdbReader = null;
if (File.Exists(pdbFileName))
{
using (var pdbStream = File.OpenRead(pdbFileName))
{
pdbReader = new PdbReader(pdbStream, host);
}
}
sourceProviderForAssembly.Add(module.ContainingAssembly, pdbReader);
return Tuple.Create(module.ContainingAssembly, pdbReader as ISourceLocationProvider);
}
}
}