提交 34f30800 编写于 作者: J Jared Parsons

Re-arranging portable TestUtilities part 4

Fix the factored out runtime code to properly execute the compiler
compiled test code in AppDomains.
上级 28f4caa4
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Roslyn.Test.Utilities;
namespace Microsoft.CodeAnalysis.Test.Utilities.CodeRuntime namespace Microsoft.CodeAnalysis.Test.Utilities.CodeRuntime
{ {
...@@ -73,7 +74,7 @@ internal Assembly GetOrLoad(ModuleData moduleData, bool reflectionOnly) ...@@ -73,7 +74,7 @@ internal Assembly GetOrLoad(ModuleData moduleData, bool reflectionOnly)
return assembly; return assembly;
} }
var loadedAssembly = RuntimeAssemblyManager.LoadAsAssembly(moduleData.SimpleName, moduleData.Image, reflectionOnly); var loadedAssembly = DesktopRuntimeUtil.LoadAsAssembly(moduleData.SimpleName, moduleData.Image, reflectionOnly);
// Validate the loaded assembly matches the value that we now have in the cache. // Validate the loaded assembly matches the value that we now have in the cache.
if (!cache.TryGetValue(moduleData.Mvid, out assembly)) if (!cache.TryGetValue(moduleData.Mvid, out assembly))
......
...@@ -106,8 +106,13 @@ private RuntimeData CreateAndInitializeRuntimeData(IEnumerable<ModuleData> compi ...@@ -106,8 +106,13 @@ private RuntimeData CreateAndInitializeRuntimeData(IEnumerable<ModuleData> compi
// Many prominent assemblys like mscorlib are already in the RuntimeAssemblyManager. Only // Many prominent assemblys like mscorlib are already in the RuntimeAssemblyManager. Only
// add in the delta values to reduce serialization overhead going across AppDomains. // add in the delta values to reduce serialization overhead going across AppDomains.
var manager = runtimeData.Manager; var manager = runtimeData.Manager;
var missingList = manager.GetMissing(allModules.Select(x => x.Id).ToList()); var missingList = manager
var deltaList = allModules.Where(x => missingList.Contains(x.Id)).ToList(); .GetMissing(allModules.Select(x => new RuntimeModuleDataId(x.Id)).ToList())
.Select(x => x.Id);
var deltaList = allModules
.Where(x => missingList.Contains(x.Id))
.Select(x => new RuntimeModuleData(x))
.ToList();
manager.AddModuleData(deltaList); manager.AddModuleData(deltaList);
manager.AddMainModuleMvid(mainModuleId.Mvid); manager.AddMainModuleMvid(mainModuleId.Mvid);
...@@ -141,7 +146,7 @@ private static RuntimeData TryGetCachedRuntimeData(IEnumerable<ModuleData> modul ...@@ -141,7 +146,7 @@ private static RuntimeData TryGetCachedRuntimeData(IEnumerable<ModuleData> modul
{ {
var data = s_runtimeDataCache[i]; var data = s_runtimeDataCache[i];
var manager = data.Manager; var manager = data.Manager;
if (!manager.HasConflicts(modules.Select(x => x.Id).ToList())) if (!manager.HasConflicts(modules.Select(x => new RuntimeModuleDataId(x.Id)).ToList()))
{ {
s_runtimeDataCache.RemoveAt(i); s_runtimeDataCache.RemoveAt(i);
return data; return data;
......
...@@ -24,7 +24,7 @@ private struct AssemblyData ...@@ -24,7 +24,7 @@ private struct AssemblyData
internal ModuleData ModuleData { get; } internal ModuleData ModuleData { get; }
internal Assembly Assembly { get; } internal Assembly Assembly { get; }
internal Kind Kind => Assembly != null ? Kind.Assembly : Kind.ModuleData; internal Kind Kind => Assembly != null ? Kind.Assembly : Kind.ModuleData;
internal ModuleDataId Id => Assembly != null ? new ModuleDataId(Assembly) : ModuleData.Id; internal ModuleDataId Id => Assembly != null ? new ModuleDataId(Assembly, Assembly.ManifestModule.ModuleVersionId) : ModuleData.Id;
internal AssemblyData(ModuleData moduleData) internal AssemblyData(ModuleData moduleData)
{ {
...@@ -138,7 +138,7 @@ private bool IsOwned(Assembly assembly) ...@@ -138,7 +138,7 @@ private bool IsOwned(Assembly assembly)
|| _loadedAssemblies.Contains(assembly); || _loadedAssemblies.Contains(assembly);
} }
internal bool ContainsNetModules() public bool ContainsNetModules()
{ {
return _containsNetModules; return _containsNetModules;
} }
...@@ -153,9 +153,9 @@ public override object InitializeLifetimeService() ...@@ -153,9 +153,9 @@ public override object InitializeLifetimeService()
/// return values that are already present. /// return values that are already present.
/// </summary> /// </summary>
/// <param name="modules"></param> /// <param name="modules"></param>
internal void AddModuleData(IEnumerable<ModuleData> modules) public void AddModuleData(List<RuntimeModuleData> modules)
{ {
foreach (var module in modules) foreach (var module in modules.Select(x => x.Data))
{ {
// If the module is already added then nothing else to do // If the module is already added then nothing else to do
AssemblyData assemblyData; AssemblyData assemblyData;
...@@ -179,9 +179,9 @@ internal void AddModuleData(IEnumerable<ModuleData> modules) ...@@ -179,9 +179,9 @@ internal void AddModuleData(IEnumerable<ModuleData> modules)
} }
} }
public bool HasConflicts(IEnumerable<ModuleDataId> moduleDataIds) public bool HasConflicts(List<RuntimeModuleDataId> moduleDataIds)
{ {
foreach (var id in moduleDataIds) foreach (var id in moduleDataIds.Select(x => x.Id))
{ {
AssemblyData assemblyData; AssemblyData assemblyData;
bool fullMatch; bool fullMatch;
...@@ -203,16 +203,16 @@ private void AddAssemblyData(AssemblyData assemblyData) ...@@ -203,16 +203,16 @@ private void AddAssemblyData(AssemblyData assemblyData)
/// <summary> /// <summary>
/// Return the subset of IDs passed in which are not currently tracked by this instance. /// Return the subset of IDs passed in which are not currently tracked by this instance.
/// </summary> /// </summary>
public List<ModuleDataId> GetMissing(IEnumerable<ModuleDataId> moduleIds) public List<RuntimeModuleDataId> GetMissing(List<RuntimeModuleDataId> moduleIds)
{ {
var list = new List<ModuleDataId>(); var list = new List<RuntimeModuleDataId>();
foreach (var id in moduleIds) foreach (var id in moduleIds.Select(x => x.Id))
{ {
AssemblyData other; AssemblyData other;
bool fullMatch; bool fullMatch;
if (!TryGetMatchingByFullName(id, out other, out fullMatch) || !fullMatch) if (!TryGetMatchingByFullName(id, out other, out fullMatch) || !fullMatch)
{ {
list.Add(id); list.Add(new RuntimeModuleDataId(id));
} }
} }
...@@ -284,33 +284,7 @@ private Assembly AssemblyResolve(ResolveEventArgs args, bool reflectionOnly) ...@@ -284,33 +284,7 @@ private Assembly AssemblyResolve(ResolveEventArgs args, bool reflectionOnly)
return null; return null;
} }
/// <summary> private Assembly GetAssembly(string fullName, bool reflectionOnly)
/// Loads given array of bytes as an assembly image using <see cref="System.Reflection.Assembly.Load"/> or <see cref="System.Reflection.Assembly.ReflectionOnlyLoad"/>.
/// </summary>
internal static Assembly LoadAsAssembly(string moduleName, ImmutableArray<byte> rawAssembly, bool reflectionOnly = false)
{
Debug.Assert(!rawAssembly.IsDefault);
byte[] bytes = rawAssembly.ToArray();
try
{
if (reflectionOnly)
{
return Assembly.ReflectionOnlyLoad(bytes);
}
else
{
return Assembly.Load(bytes);
}
}
catch (Exception ex)
{
throw new Exception($"Exception loading {moduleName} reflectionOnly:{reflectionOnly}", ex);
}
}
internal Assembly GetAssembly(string fullName, bool reflectionOnly)
{ {
AssemblyData data; AssemblyData data;
if (!_fullNameToAssemblyDataMap.TryGetValue(fullName, out data)) if (!_fullNameToAssemblyDataMap.TryGetValue(fullName, out data))
...@@ -355,7 +329,7 @@ private Module ModuleResolve(object sender, ResolveEventArgs args) ...@@ -355,7 +329,7 @@ private Module ModuleResolve(object sender, ResolveEventArgs args)
return assembly.LoadModule(args.Name, rawModule.ToArray()); return assembly.LoadModule(args.Name, rawModule.ToArray());
} }
internal SortedSet<string> GetMemberSignaturesFromMetadata(string fullyQualifiedTypeName, string memberName, IEnumerable<ModuleDataId> searchModules) public SortedSet<string> GetMemberSignaturesFromMetadata(string fullyQualifiedTypeName, string memberName, List<ModuleDataId> searchModules)
{ {
try try
{ {
...@@ -384,7 +358,7 @@ internal SortedSet<string> GetMemberSignaturesFromMetadata(string fullyQualified ...@@ -384,7 +358,7 @@ internal SortedSet<string> GetMemberSignaturesFromMetadata(string fullyQualified
} }
} }
internal SortedSet<string> GetFullyQualifiedTypeNames(string assemblyName) private SortedSet<string> GetFullyQualifiedTypeNames(string assemblyName)
{ {
var typeNames = new SortedSet<string>(); var typeNames = new SortedSet<string>();
Assembly assembly = GetAssembly(assemblyName, true); Assembly assembly = GetAssembly(assemblyName, true);
...@@ -396,7 +370,7 @@ internal SortedSet<string> GetFullyQualifiedTypeNames(string assemblyName) ...@@ -396,7 +370,7 @@ internal SortedSet<string> GetFullyQualifiedTypeNames(string assemblyName)
public int Execute(string moduleName, int expectedOutputLength, out string output) public int Execute(string moduleName, int expectedOutputLength, out string output)
{ {
ImmutableArray<byte> bytes = GetModuleBytesByName(moduleName); ImmutableArray<byte> bytes = GetModuleBytesByName(moduleName);
Assembly assembly = LoadAsAssembly(moduleName, bytes); Assembly assembly = DesktopRuntimeUtil.LoadAsAssembly(moduleName, bytes);
MethodInfo entryPoint = assembly.EntryPoint; MethodInfo entryPoint = assembly.EntryPoint;
Debug.Assert(entryPoint != null, "Attempting to execute an assembly that has no entrypoint; is your test trying to execute a DLL?"); Debug.Assert(entryPoint != null, "Attempting to execute an assembly that has no entrypoint; is your test trying to execute a DLL?");
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.Emit;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Test.Utilities.CodeRuntime
{
[Serializable]
public struct RuntimeModuleDataId : ISerializable
{
public ModuleDataId Id { get; }
public RuntimeModuleDataId(ModuleDataId id)
{
Id = id;
}
private RuntimeModuleDataId(SerializationInfo info, StreamingContext context)
{
var simpleName = info.GetString(nameof(Id.SimpleName));
var fullName = info.GetString(nameof(Id.FullName));
var mvid = (Guid)info.GetValue(nameof(Id.Mvid), typeof(Guid));
Id = new ModuleDataId(simpleName, fullName, mvid);
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue(nameof(Id.SimpleName), Id.SimpleName);
info.AddValue(nameof(Id.FullName), Id.FullName);
info.AddValue(nameof(Id.Mvid), Id.Mvid);
}
}
[Serializable, DebuggerDisplay("{GetDebuggerDisplay()}")]
public sealed class RuntimeModuleData : ISerializable
{
public ModuleData Data { get; }
public RuntimeModuleData(ModuleData data)
{
Data = data;
}
private RuntimeModuleData(SerializationInfo info, StreamingContext context)
{
var id = (RuntimeModuleDataId)info.GetValue(nameof(ModuleData.Id), typeof(RuntimeModuleDataId));
var kind = (OutputKind)info.GetInt32(nameof(ModuleData.Kind));
var image = info.GetByteArray(nameof(ModuleData.Image));
var pdb = info.GetByteArray(nameof(ModuleData.Pdb));
var inMemoryModule = info.GetBoolean(nameof(ModuleData.InMemoryModule));
Data = new ModuleData(id.Id, kind, image, pdb, inMemoryModule);
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue(nameof(ModuleData.Id), new RuntimeModuleDataId(Data.Id));
info.AddValue(nameof(ModuleData.Kind), (int)Data.Kind);
info.AddByteArray(nameof(ModuleData.Image), Data.Image);
info.AddByteArray(nameof(ModuleData.Pdb), Data.Pdb);
info.AddValue(nameof(ModuleData.InMemoryModule), Data.InMemoryModule);
}
}
}
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO; using System.IO;
using System.IO.Compression; using System.IO.Compression;
using System.Linq; using System.Linq;
...@@ -63,5 +65,32 @@ internal static MetadataReference CreateReflectionEmitAssembly(Action<ModuleBuil ...@@ -63,5 +65,32 @@ internal static MetadataReference CreateReflectionEmitAssembly(Action<ModuleBuil
return MetadataReference.CreateFromImage(image); return MetadataReference.CreateFromImage(image);
} }
} }
/// <summary>
/// Loads given array of bytes as an assembly image using <see cref="System.Reflection.Assembly.Load"/> or <see cref="System.Reflection.Assembly.ReflectionOnlyLoad"/>.
/// </summary>
internal static Assembly LoadAsAssembly(string moduleName, ImmutableArray<byte> rawAssembly, bool reflectionOnly = false)
{
Debug.Assert(!rawAssembly.IsDefault);
byte[] bytes = rawAssembly.ToArray();
try
{
if (reflectionOnly)
{
return Assembly.ReflectionOnlyLoad(bytes);
}
else
{
return Assembly.Load(bytes);
}
}
catch (Exception ex)
{
throw new Exception($"Exception loading {moduleName} reflectionOnly:{reflectionOnly}", ex);
}
}
} }
} }
...@@ -88,6 +88,7 @@ ...@@ -88,6 +88,7 @@
<Compile Include="AppDomainUtils.cs" /> <Compile Include="AppDomainUtils.cs" />
<Compile Include="CLRHelpers.cs" /> <Compile Include="CLRHelpers.cs" />
<Compile Include="CodeRuntime\DesktopRuntimeEnvironmentFactory.cs" /> <Compile Include="CodeRuntime\DesktopRuntimeEnvironmentFactory.cs" />
<Compile Include="CodeRuntime\RuntimeModuleData.cs" />
<Compile Include="DesktopRuntimeUtil.cs" /> <Compile Include="DesktopRuntimeUtil.cs" />
<Compile Include="InstrumentationChecker.cs" /> <Compile Include="InstrumentationChecker.cs" />
<Compile Include="ConditionalFactAttribute.cs" /> <Compile Include="ConditionalFactAttribute.cs" />
......
...@@ -31,7 +31,7 @@ private static IRuntimeEnvironmentFactory GetFactoryImplementation() ...@@ -31,7 +31,7 @@ private static IRuntimeEnvironmentFactory GetFactoryImplementation()
if (DesktopShim.FileNotFoundException.Type != null) if (DesktopShim.FileNotFoundException.Type != null)
{ {
assemblyName = "Roslyn.Test.Utilities.Desktop"; assemblyName = "Roslyn.Test.Utilities.Desktop";
typeName = "Roslyn.Test.Utilities.DesktopRuntimeEnvironmentFactory"; typeName = "Microsoft.CodeAnalysis.Test.Utilities.CodeRuntime.DesktopRuntimeEnvironmentFactory";
} }
else else
{ {
......
...@@ -57,7 +57,7 @@ public static void IlasmTempAssembly(string declarations, bool appendDefaultHead ...@@ -57,7 +57,7 @@ public static void IlasmTempAssembly(string declarations, bool appendDefaultHead
sourceFile.WriteAllText(completeIL); sourceFile.WriteAllText(completeIL);
var ilasmPath = Path.Combine( var ilasmPath = Path.Combine(
CorLightup.Desktop.GetAssemblyLocation(typeof(object).GetTypeInfo().Assembly), Path.GetDirectoryName(CorLightup.Desktop.GetAssemblyLocation(typeof(object).GetTypeInfo().Assembly)),
"ilasm.exe"); "ilasm.exe");
var arguments = string.Format( var arguments = string.Format(
......
...@@ -24,12 +24,11 @@ public struct ModuleDataId ...@@ -24,12 +24,11 @@ public struct ModuleDataId
public string FullName { get; } public string FullName { get; }
public Guid Mvid { get; } public Guid Mvid { get; }
public ModuleDataId(Assembly assembly) public ModuleDataId(Assembly assembly, Guid mvid)
{ {
SimpleName = assembly.GetName().Name; SimpleName = assembly.GetName().Name;
FullName = assembly.FullName; FullName = assembly.FullName;
// Replace with mvid Mvid = mvid;
Mvid = default(Guid);
} }
public ModuleDataId(string simpleName, string fullName, Guid mvid) public ModuleDataId(string simpleName, string fullName, Guid mvid)
...@@ -77,6 +76,15 @@ public ModuleData(AssemblyIdentity identity, OutputKind kind, ImmutableArray<byt ...@@ -77,6 +76,15 @@ public ModuleData(AssemblyIdentity identity, OutputKind kind, ImmutableArray<byt
this.InMemoryModule = inMemoryModule; this.InMemoryModule = inMemoryModule;
} }
public ModuleData(ModuleDataId id, OutputKind kind, ImmutableArray<byte> image, ImmutableArray<byte> pdb, bool inMemoryModule)
{
this.Id = id;
this.Kind = kind;
this.Image = image;
this.Pdb = pdb;
this.InMemoryModule = inMemoryModule;
}
private static Guid GetMvid(ImmutableArray<byte> image) private static Guid GetMvid(ImmutableArray<byte> image)
{ {
using (var metadata = ModuleMetadata.CreateFromImage(image)) using (var metadata = ModuleMetadata.CreateFromImage(image))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册