提交 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 @@
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Roslyn.Test.Utilities;
namespace Microsoft.CodeAnalysis.Test.Utilities.CodeRuntime
{
......@@ -73,7 +74,7 @@ internal Assembly GetOrLoad(ModuleData moduleData, bool reflectionOnly)
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.
if (!cache.TryGetValue(moduleData.Mvid, out assembly))
......
......@@ -106,8 +106,13 @@ private RuntimeData CreateAndInitializeRuntimeData(IEnumerable<ModuleData> compi
// Many prominent assemblys like mscorlib are already in the RuntimeAssemblyManager. Only
// add in the delta values to reduce serialization overhead going across AppDomains.
var manager = runtimeData.Manager;
var missingList = manager.GetMissing(allModules.Select(x => x.Id).ToList());
var deltaList = allModules.Where(x => missingList.Contains(x.Id)).ToList();
var missingList = manager
.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.AddMainModuleMvid(mainModuleId.Mvid);
......@@ -141,7 +146,7 @@ private static RuntimeData TryGetCachedRuntimeData(IEnumerable<ModuleData> modul
{
var data = s_runtimeDataCache[i];
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);
return data;
......
......@@ -24,7 +24,7 @@ private struct AssemblyData
internal ModuleData ModuleData { get; }
internal Assembly Assembly { get; }
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)
{
......@@ -138,7 +138,7 @@ private bool IsOwned(Assembly assembly)
|| _loadedAssemblies.Contains(assembly);
}
internal bool ContainsNetModules()
public bool ContainsNetModules()
{
return _containsNetModules;
}
......@@ -153,9 +153,9 @@ public override object InitializeLifetimeService()
/// return values that are already present.
/// </summary>
/// <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
AssemblyData assemblyData;
......@@ -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;
bool fullMatch;
......@@ -203,16 +203,16 @@ private void AddAssemblyData(AssemblyData assemblyData)
/// <summary>
/// Return the subset of IDs passed in which are not currently tracked by this instance.
/// </summary>
public List<ModuleDataId> GetMissing(IEnumerable<ModuleDataId> moduleIds)
public List<RuntimeModuleDataId> GetMissing(List<RuntimeModuleDataId> moduleIds)
{
var list = new List<ModuleDataId>();
foreach (var id in moduleIds)
var list = new List<RuntimeModuleDataId>();
foreach (var id in moduleIds.Select(x => x.Id))
{
AssemblyData other;
bool 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)
return null;
}
/// <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);
}
}
internal Assembly GetAssembly(string fullName, bool reflectionOnly)
private Assembly GetAssembly(string fullName, bool reflectionOnly)
{
AssemblyData data;
if (!_fullNameToAssemblyDataMap.TryGetValue(fullName, out data))
......@@ -355,7 +329,7 @@ private Module ModuleResolve(object sender, ResolveEventArgs args)
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
{
......@@ -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>();
Assembly assembly = GetAssembly(assemblyName, true);
......@@ -396,7 +370,7 @@ internal SortedSet<string> GetFullyQualifiedTypeNames(string assemblyName)
public int Execute(string moduleName, int expectedOutputLength, out string output)
{
ImmutableArray<byte> bytes = GetModuleBytesByName(moduleName);
Assembly assembly = LoadAsAssembly(moduleName, bytes);
Assembly assembly = DesktopRuntimeUtil.LoadAsAssembly(moduleName, bytes);
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?");
......
// 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.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
......@@ -63,5 +65,32 @@ internal static MetadataReference CreateReflectionEmitAssembly(Action<ModuleBuil
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 @@
<Compile Include="AppDomainUtils.cs" />
<Compile Include="CLRHelpers.cs" />
<Compile Include="CodeRuntime\DesktopRuntimeEnvironmentFactory.cs" />
<Compile Include="CodeRuntime\RuntimeModuleData.cs" />
<Compile Include="DesktopRuntimeUtil.cs" />
<Compile Include="InstrumentationChecker.cs" />
<Compile Include="ConditionalFactAttribute.cs" />
......
......@@ -31,7 +31,7 @@ private static IRuntimeEnvironmentFactory GetFactoryImplementation()
if (DesktopShim.FileNotFoundException.Type != null)
{
assemblyName = "Roslyn.Test.Utilities.Desktop";
typeName = "Roslyn.Test.Utilities.DesktopRuntimeEnvironmentFactory";
typeName = "Microsoft.CodeAnalysis.Test.Utilities.CodeRuntime.DesktopRuntimeEnvironmentFactory";
}
else
{
......
......@@ -57,7 +57,7 @@ public static void IlasmTempAssembly(string declarations, bool appendDefaultHead
sourceFile.WriteAllText(completeIL);
var ilasmPath = Path.Combine(
CorLightup.Desktop.GetAssemblyLocation(typeof(object).GetTypeInfo().Assembly),
Path.GetDirectoryName(CorLightup.Desktop.GetAssemblyLocation(typeof(object).GetTypeInfo().Assembly)),
"ilasm.exe");
var arguments = string.Format(
......
......@@ -24,12 +24,11 @@ public struct ModuleDataId
public string FullName { get; }
public Guid Mvid { get; }
public ModuleDataId(Assembly assembly)
public ModuleDataId(Assembly assembly, Guid mvid)
{
SimpleName = assembly.GetName().Name;
FullName = assembly.FullName;
// Replace with mvid
Mvid = default(Guid);
Mvid = mvid;
}
public ModuleDataId(string simpleName, string fullName, Guid mvid)
......@@ -77,6 +76,15 @@ public ModuleData(AssemblyIdentity identity, OutputKind kind, ImmutableArray<byt
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)
{
using (var metadata = ModuleMetadata.CreateFromImage(image))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册