From 38ce4d3524b4e738d80534690387d72092b7efaf Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Tue, 18 May 2021 11:18:09 -0700 Subject: [PATCH 01/24] add GuidPatch project and starter target --- nuget/Microsoft.Windows.CsWinRT.targets | 6 + src/Perf/GuidPatch/CecilExtensions.cs | 110 ++++ src/Perf/GuidPatch/FolderAssemblyResolver.cs | 30 ++ src/Perf/GuidPatch/GuidPatch.csproj | 14 + src/Perf/GuidPatch/GuidPatcher.cs | 364 ++++++++++++++ src/Perf/GuidPatch/Program.cs | 26 + src/Perf/GuidPatch/SignatureEmitter.cs | 502 +++++++++++++++++++ src/Perf/GuidPatch/SignatureGenerator.cs | 212 ++++++++ src/cswinrt.sln | 75 +++ 9 files changed, 1339 insertions(+) create mode 100644 src/Perf/GuidPatch/CecilExtensions.cs create mode 100644 src/Perf/GuidPatch/FolderAssemblyResolver.cs create mode 100644 src/Perf/GuidPatch/GuidPatch.csproj create mode 100644 src/Perf/GuidPatch/GuidPatcher.cs create mode 100644 src/Perf/GuidPatch/Program.cs create mode 100644 src/Perf/GuidPatch/SignatureEmitter.cs create mode 100644 src/Perf/GuidPatch/SignatureGenerator.cs diff --git a/nuget/Microsoft.Windows.CsWinRT.targets b/nuget/Microsoft.Windows.CsWinRT.targets index 8a0186aab..2ce814b4d 100644 --- a/nuget/Microsoft.Windows.CsWinRT.targets +++ b/nuget/Microsoft.Windows.CsWinRT.targets @@ -147,6 +147,12 @@ $(CsWinRTFilters) + + + + + + diff --git a/src/Perf/GuidPatch/CecilExtensions.cs b/src/Perf/GuidPatch/CecilExtensions.cs new file mode 100644 index 000000000..753f020ce --- /dev/null +++ b/src/Perf/GuidPatch/CecilExtensions.cs @@ -0,0 +1,110 @@ +using Mono.Cecil; +using Mono.Cecil.Cil; +using System; +using System.Linq; + +namespace GuidPatch +{ + static class CecilExtensions + { + internal static Guid? ReadGuidFromAttribute(this TypeReference type, TypeReference guidAttributeType, AssemblyDefinition winrtRuntimeAssembly) + { + TypeDefinition def = type.Resolve(); + var guidAttr = def.CustomAttributes.FirstOrDefault(attr => attr.AttributeType.Resolve() == guidAttributeType); + if (guidAttr is null) + { + TypeDefinition abiType = def.GetCswinrtAbiTypeDefinition(winrtRuntimeAssembly); + if (abiType is not null) + { + return abiType.ReadGuidFromAttribute(guidAttributeType, winrtRuntimeAssembly); + } + return null; + } + return new Guid((string)guidAttr.ConstructorArguments[0].Value); + } + + internal static TypeDefinition GetCswinrtAbiTypeDefinition(this TypeReference type, AssemblyDefinition winrtRuntimeAssembly) + { + var resolvedType = type.Resolve(); + + return resolvedType.Module.GetType($"ABI.{resolvedType.FullName}") ?? + winrtRuntimeAssembly.MainModule.GetType($"ABI.{resolvedType.FullName}"); + } + + internal static MethodDefinition CreateIIDDataGetter(TypeReference type, Guid iidValue, TypeDefinition dataBlockType, TypeDefinition parentType, TypeReference readOnlySpanOfByte, MethodReference readOnlySpanOfByteCtor) + { + var guidDataMethod = new MethodDefinition($"{type.FullName}", MethodAttributes.Assembly | MethodAttributes.Static, readOnlySpanOfByte); + + WriteIIDDataGetterBody(guidDataMethod, type, iidValue, dataBlockType, parentType, readOnlySpanOfByteCtor); + return guidDataMethod; + } + + internal static void WriteIIDDataGetterBody(MethodDefinition method, TypeReference type, Guid iidValue, TypeDefinition dataBlockType, TypeDefinition parentType, MethodReference readOnlySpanOfByteCtor) + { + var guidDataField = new FieldDefinition($"{type.FullName}", FieldAttributes.Private | FieldAttributes.Static | FieldAttributes.InitOnly | FieldAttributes.HasFieldRVA, dataBlockType) + { + InitialValue = iidValue.ToByteArray() + }; + parentType.Fields.Add(guidDataField); + + var ilProcessor = method.Body.GetILProcessor(); + ilProcessor.Clear(); + ilProcessor.Append(Instruction.Create(OpCodes.Ldsflda, guidDataField)); + ilProcessor.Append(Instruction.Create(OpCodes.Ldc_I4, 16)); + ilProcessor.Append(Instruction.Create(OpCodes.Newobj, readOnlySpanOfByteCtor)); + ilProcessor.Append(Instruction.Create(OpCodes.Ret)); + } + + internal static TypeDefinition GetOrCreateDataBlockType(TypeDefinition parentType, int size) + { + if (size < 0 || size > ushort.MaxValue) + { + throw new ArgumentOutOfRangeException(nameof(size)); + } + + string typeName = $"__StaticDataBlock<>Size={size}"; + + var typeRef = new TypeReference(null, typeName, parentType.Module, parentType.Module) + { + DeclaringType = parentType + }; + + if (typeRef.Resolve() is TypeDefinition td) + { + return td; + } + + td = new TypeDefinition(null, typeName, TypeAttributes.AutoClass | TypeAttributes.Sealed | TypeAttributes.NestedAssembly | TypeAttributes.SequentialLayout | TypeAttributes.AnsiClass, new TypeReference("System", "ValueType", parentType.Module, parentType.Module.TypeSystem.CoreLibrary)) + { + PackingSize = 1, + ClassSize = size + }; + + parentType.NestedTypes.Add(td); + + return td; + } + + internal static TypeReference? FindTypeReference(ModuleDefinition module, string ns, string name, string basicAssemblyName, bool isValueType) + { + foreach (var asm in module.AssemblyReferences) + { + if (asm.Name == basicAssemblyName || asm.Name.StartsWith($"{basicAssemblyName},")) + { + TypeReference typeRef = new TypeReference(ns, name, module, asm, isValueType); + if (typeRef.Resolve() != null) + { + return module.ImportReference(typeRef); + } + break; + } + } + var resolved = module.AssemblyResolver.Resolve(new AssemblyNameReference(basicAssemblyName, default)); + if (resolved is null) + { + return null; + } + return resolved.MainModule.Types.FirstOrDefault(t => t.Namespace == ns && t.Name == name); + } + } +} diff --git a/src/Perf/GuidPatch/FolderAssemblyResolver.cs b/src/Perf/GuidPatch/FolderAssemblyResolver.cs new file mode 100644 index 000000000..719862297 --- /dev/null +++ b/src/Perf/GuidPatch/FolderAssemblyResolver.cs @@ -0,0 +1,30 @@ +using Mono.Cecil; +using System; +using System.IO; +using System.Linq; + +namespace GuidPatch +{ + class FolderAssemblyResolver : DefaultAssemblyResolver + { + public FolderAssemblyResolver(params DirectoryInfo[] directories) + { + foreach (var file in directories.SelectMany(d => d.EnumerateFiles("*.dll"))) + { + try + { + var definition = AssemblyDefinition.ReadAssembly(file.FullName, new ReaderParameters(ReadingMode.Deferred) + { + InMemory = true, + ReadWrite = false, + AssemblyResolver = this + }); + RegisterAssembly(definition); + } + catch (Exception) + { + } + } + } + } +} diff --git a/src/Perf/GuidPatch/GuidPatch.csproj b/src/Perf/GuidPatch/GuidPatch.csproj new file mode 100644 index 000000000..c9ca52748 --- /dev/null +++ b/src/Perf/GuidPatch/GuidPatch.csproj @@ -0,0 +1,14 @@ + + + + Exe + net5.0 + enable + AnyCPU;x64;x86 + + + + + + + diff --git a/src/Perf/GuidPatch/GuidPatcher.cs b/src/Perf/GuidPatch/GuidPatcher.cs new file mode 100644 index 000000000..2af033fb1 --- /dev/null +++ b/src/Perf/GuidPatch/GuidPatcher.cs @@ -0,0 +1,364 @@ +using Mono.Cecil; +using Mono.Cecil.Cil; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; + + +namespace GuidPatch +{ + class GuidPatcher + { + private readonly AssemblyDefinition assembly; + private readonly AssemblyDefinition winRTRuntimeAssembly; + private readonly TypeDefinition guidType; + private readonly GenericInstanceType readOnlySpanOfByte; + private readonly MethodReference readOnlySpanOfByteCtor; + private readonly MethodReference guidCtor; + private readonly TypeDefinition? guidAttributeType; + private readonly MethodDefinition getTypeFromHandleMethod; + private readonly TypeDefinition? guidGeneratorType; + private readonly MethodDefinition? getIidMethod; + private readonly MethodDefinition? createIidMethod; + private readonly MethodDefinition? getHelperTypeMethod; + + private readonly Dictionary ClosedTypeGuidDataMapping = new Dictionary(); + private readonly TypeDefinition guidImplementationDetailsType; + private readonly TypeDefinition guidDataBlockType; + private SignatureGenerator signatureGenerator; + + public GuidPatcher(string assemblyPath, IAssemblyResolver assemblyResolver) + { + assembly = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters(ReadingMode.Deferred) + { + ReadWrite = true, + InMemory = true, + AssemblyResolver = assemblyResolver, + ThrowIfSymbolsAreNotMatching = false, + SymbolReaderProvider = new DefaultSymbolReaderProvider(false), + ApplyWindowsRuntimeProjections = false + }); + + winRTRuntimeAssembly = assemblyResolver.Resolve(new AssemblyNameReference("WinRT.Runtime", default)); + + guidImplementationDetailsType = new TypeDefinition(null, "", TypeAttributes.AutoClass | TypeAttributes.Sealed, assembly.MainModule.TypeSystem.Object); + + assembly.MainModule.Types.Add(guidImplementationDetailsType); + + guidDataBlockType = CecilExtensions.GetOrCreateDataBlockType(guidImplementationDetailsType, Unsafe.SizeOf()); + + var systemType = new TypeReference("System", "Type", assembly.MainModule, assembly.MainModule.TypeSystem.CoreLibrary).Resolve(); + + guidType = new TypeReference("System", "Guid", assembly.MainModule, assembly.MainModule.TypeSystem.CoreLibrary).Resolve(); + + readOnlySpanOfByte = new GenericInstanceType(new TypeReference("System", "ReadOnlySpan`1", assembly.MainModule, assembly.MainModule.TypeSystem.CoreLibrary, true)) + { + GenericArguments = + { + assembly.MainModule.TypeSystem.Byte + } + }; + + readOnlySpanOfByteCtor = assembly.MainModule.ImportReference(new MethodReference(".ctor", assembly.MainModule.TypeSystem.Void, readOnlySpanOfByte) + { + Parameters = + { + new ParameterDefinition(new PointerType(assembly.MainModule.TypeSystem.Void)), + new ParameterDefinition(assembly.MainModule.TypeSystem.Int32), + } + }); + + guidCtor = assembly.MainModule.ImportReference(guidType.Methods.First(m => m.IsConstructor && m.Parameters.Count == 1 && m.Parameters[0].ParameterType.Resolve() == readOnlySpanOfByte.Resolve())); + + getTypeFromHandleMethod = systemType.Methods.First(m => m.Name == "GetTypeFromHandle"); + + guidGeneratorType = null; + + TypeDefinition? typeExtensionsType = null; + + foreach (var asm in assembly.MainModule.AssemblyReferences) + { + if (asm.Name == "WinRT.Runtime") + { + guidGeneratorType = + new TypeReference("WinRT", "GuidGenerator", assembly.MainModule, asm).Resolve(); + typeExtensionsType = new TypeReference("WinRT", "TypeExtensions", assembly.MainModule, asm).Resolve(); + } + else if (asm.Name == "System.Runtime.InteropServices") + { + guidAttributeType = new TypeReference("System.Runtime.InteropServices", "GuidAttribute", assembly.MainModule, asm).Resolve(); + } + } + + if (guidGeneratorType is not null && typeExtensionsType is not null) + { + getIidMethod = guidGeneratorType.Methods.First(m => m.Name == "GetIID"); + createIidMethod = guidGeneratorType.Methods.First(m => m.Name == "CreateIID"); + getHelperTypeMethod = typeExtensionsType.Methods.First(m => m.Name == "GetHelperType"); + } + + signatureGenerator = new SignatureGenerator(assembly, guidAttributeType!, winRTRuntimeAssembly); + } + + public int ProcessAssembly() + { + if (guidGeneratorType is null || guidAttributeType is null) + { + return 0; + } + int numPatches = 0; + var methods = from module in assembly.Modules + from type in module.Types + from method in type.Methods + where method.HasBody + select method; + + foreach (var method in methods) + { + numPatches += ProcessMethodBody(method.Body, getTypeFromHandleMethod, getIidMethod!, createIidMethod!); + } + + return numPatches; + } + + public void SaveAssembly(string targetDirectory) + { + assembly.Write($"{targetDirectory}{Path.DirectorySeparatorChar}{assembly.Name.Name}.dll"); + } + + enum State + { + Start, + Ldtoken, + GetTypeFromHandle, + GetHelperTypeOptional + } + + private int ProcessMethodBody(MethodBody body, MethodDefinition getTypeFromHandleMethod, MethodDefinition getIidMethod, MethodDefinition createIidMethod) + { + int numberOfReplacements = 0; + TypeReference? type = null; + State state = State.Start; + int startIlIndex = -1; + int numberOfInstructionsToOverwrite = 3; + for (int i = 0; i < body.Instructions.Count; i++) + { + var instruction = body.Instructions[i]; + switch (state) + { + case State.Start: + if (instruction.OpCode.Code != Code.Ldtoken) + { + continue; + } + var typeMaybe = (TypeReference)instruction.Operand; + if (!typeMaybe.IsGenericParameter) + { + state = State.Ldtoken; + type = typeMaybe; + startIlIndex = i; + } + break; + case State.Ldtoken: + { + if (instruction.OpCode.Code != Code.Call) + { + state = State.Start; + type = null; + continue; + } + var method = ((MethodReference)instruction.Operand).Resolve(); + if (method == getTypeFromHandleMethod) + { + state = State.GetTypeFromHandle; + } + } + break; + case State.GetTypeFromHandle: + { + if (instruction.OpCode.Code != Code.Call) + { + state = State.Start; + type = null; + continue; + } + var method = ((MethodReference)instruction.Operand).Resolve(); + if (method == getHelperTypeMethod) + { + numberOfInstructionsToOverwrite++; + state = State.GetHelperTypeOptional; + continue; + } + else + { + goto case State.GetHelperTypeOptional; + } + } + case State.GetHelperTypeOptional: + { + if (instruction.OpCode.Code != Code.Call) + { + state = State.Start; + type = null; + continue; + } + var method = ((MethodReference)instruction.Operand).Resolve(); + if (method == getIidMethod || method == createIidMethod) + { + try + { + bool didPatch = false; + if (type!.IsGenericInstance) + { + didPatch = PatchGenericTypeIID(body, startIlIndex, type, numberOfInstructionsToOverwrite); + } + else + { + didPatch = PatchNonGenericTypeIID(body, startIlIndex, type, numberOfInstructionsToOverwrite); + } + + if (didPatch) + { + numberOfReplacements++; + } + } + catch (Exception ex) + { + Debug.WriteLine($"Exception thrown during patching {body.Method.FullName}: {ex}"); + } + } + else + { + state = State.Start; + type = null; + startIlIndex = -1; + } + } + break; + default: + throw new InvalidOperationException(); + } + } + return numberOfReplacements; + } + + private bool PatchNonGenericTypeIID(MethodBody body, int startILIndex, TypeReference type, int numberOfInstructionsToOverwrite) + { + if (numberOfInstructionsToOverwrite < 2) + { + return false; + } + + if (!ClosedTypeGuidDataMapping.TryGetValue(type, out var guidDataMethod)) + { + Guid? guidValue = type.ReadGuidFromAttribute(guidAttributeType!, winRTRuntimeAssembly); + if (guidValue == null) + { + return false; + } + + guidDataMethod = CecilExtensions.CreateIIDDataGetter(type, guidValue.Value, guidDataBlockType, guidImplementationDetailsType, readOnlySpanOfByte, readOnlySpanOfByteCtor); + + guidImplementationDetailsType.Methods.Add(guidDataMethod); + ClosedTypeGuidDataMapping[type] = guidDataMethod; + } + + ReplaceWithCallToGuidDataGetter(body, startILIndex, numberOfInstructionsToOverwrite, guidDataMethod); + + return true; + } + + private bool PatchGenericTypeIID(MethodBody body, int startILIndex, TypeReference type, int numberOfInstructionsToOverwrite) + { + SignaturePart rootSignaturePart = signatureGenerator.GetSignatureParts(type); + + var guidDataMethod = new MethodDefinition($"{type.FullName}", MethodAttributes.Assembly | MethodAttributes.Static, readOnlySpanOfByte); + + guidImplementationDetailsType.Methods.Add(guidDataMethod); + + var emitter = new SignatureEmitter(type, guidDataMethod); + VisitSignature(rootSignaturePart, emitter); + + emitter.EmitGuidGetter(guidDataBlockType, guidImplementationDetailsType, readOnlySpanOfByte, readOnlySpanOfByteCtor, guidGeneratorType!); + + MethodReference guidDataMethodReference = guidDataMethod; + if (guidDataMethodReference.HasGenericParameters) + { + var genericGuidDataMethodReference = new GenericInstanceMethod(guidDataMethodReference); + foreach (var param in guidDataMethodReference.GenericParameters) + { + genericGuidDataMethodReference.GenericArguments.Add(emitter.GenericParameterMapping[param]); + } + guidDataMethodReference = genericGuidDataMethodReference; + } + + ReplaceWithCallToGuidDataGetter(body, startILIndex, numberOfInstructionsToOverwrite, guidDataMethodReference); + return true; + } + + private void ReplaceWithCallToGuidDataGetter(MethodBody body, int startILIndex, int numberOfInstructionsToOverwrite, MethodReference guidDataMethod) + { + var il = body.GetILProcessor(); + il.Replace(startILIndex, Instruction.Create(OpCodes.Call, guidDataMethod)); + il.Replace(startILIndex + 1, Instruction.Create(OpCodes.Newobj, guidCtor)); + for (int i = 2; i < numberOfInstructionsToOverwrite; i++) + { + il.Replace(startILIndex + i, Instruction.Create(OpCodes.Nop)); + } + } + + private void VisitSignature(SignaturePart rootSignaturePart, SignatureEmitter emitter) + { + switch (rootSignaturePart) + { + case BasicSignaturePart basic: + { + emitter.PushString(basic.Type switch + { + SignatureType.@string => "string", + SignatureType.iinspectable => "cinterface(IInspectable)", + _ => basic.Type.ToString() + }); + } + break; + case SignatureWithChildren group: + { + emitter.PushString($"{group.GroupingName}("); + emitter.PushString(group.ThisEntitySignature); + foreach (var item in group.ChildrenSignatures) + { + emitter.PushString(";"); + VisitSignature(item, emitter); + } + emitter.PushString(")"); + } + break; + case GuidSignature guid: + { + emitter.PushString(guid.IID.ToString("B")); + } + break; + case NonGenericDelegateSignature del: + { + emitter.PushString($"delegate({del.DelegateIID:B}"); + } + break; + case UninstantiatedGeneric gen: + { + emitter.PushGenericParameter(gen.OriginalGenericParameter); + } + break; + case CustomSignatureMethod custom: + { + emitter.PushCustomSignature(custom.Method); + } + break; + default: + break; + } + } + } +} diff --git a/src/Perf/GuidPatch/Program.cs b/src/Perf/GuidPatch/Program.cs new file mode 100644 index 000000000..0f993eb01 --- /dev/null +++ b/src/Perf/GuidPatch/Program.cs @@ -0,0 +1,26 @@ +using System; + +namespace GuidPatch +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("Hello World!"); + + /* + var resolver = new DefaultAssemblyResolver(); + resolver.AddSearchDirectory("TestData"); + resolver.AddSearchDirectory("C:/Program Files/dotnet/packs/Microsoft.NETCore.App.Ref/5.0.0/ref/net5.0"); + var guidPatcher = new GuidPatcher( + "TestData/Windows.dll", + resolver); + int numPatches = guidPatcher.ProcessAssembly(); + Directory.CreateDirectory("Output"); + guidPatcher.SaveAssembly("Output"); + + Console.WriteLine($"{numPatches} IID calculations/fetches patched"); + */ + } + } +} diff --git a/src/Perf/GuidPatch/SignatureEmitter.cs b/src/Perf/GuidPatch/SignatureEmitter.cs new file mode 100644 index 000000000..f0722b783 --- /dev/null +++ b/src/Perf/GuidPatch/SignatureEmitter.cs @@ -0,0 +1,502 @@ +using Mono.Cecil; +using Mono.Cecil.Cil; +using System; +using System.Buffers.Binary; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Security.Cryptography; +using System.Text; + +namespace GuidPatch +{ + sealed class SignatureEmitter + { + private static Guid WinRTPinterfaceNamespace = new("d57af411-737b-c042-abae-878b1e16adee"); + private StringBuilder? currentStringBuilder; + private readonly List signatureSteps = new(); + private readonly Dictionary originalGenericParameterToGetterParameterMapping = new(); + private readonly Dictionary getterParameterToOriginalGenericParameterMapping = new(); + private readonly TypeReference describedType; + private readonly MethodDefinition guidDataGetterMethod; + + public IReadOnlyDictionary GenericParameterMapping => getterParameterToOriginalGenericParameterMapping; + + record SignatureStep; + + sealed record StringStep(string StaticSignatureString) : SignatureStep; + + sealed record RuntimeGenericSignatureStep(GenericParameter OriginalTypeParameter, GenericParameter NewTypeParameter) : SignatureStep; + + sealed record RuntimeCustomSignatureStep(MethodReference method) : SignatureStep; + + public SignatureEmitter(TypeReference describedType, MethodDefinition guidDataGetterMethod) + { + this.describedType = describedType; + this.guidDataGetterMethod = guidDataGetterMethod; + } + + public void PushString(string str) + { + if (currentStringBuilder is null) + { + currentStringBuilder = new StringBuilder(); + } + currentStringBuilder.Append(str); + } + + public void PushGenericParameter(GenericParameter typeParameter) + { + if (!originalGenericParameterToGetterParameterMapping.TryGetValue(typeParameter, out var localTypeParameter)) + { + originalGenericParameterToGetterParameterMapping[typeParameter] = localTypeParameter = new GenericParameter(guidDataGetterMethod); + getterParameterToOriginalGenericParameterMapping[localTypeParameter] = typeParameter; + guidDataGetterMethod.GenericParameters.Add(localTypeParameter); + } + if (currentStringBuilder is not null) + { + signatureSteps.Add(new StringStep(currentStringBuilder.ToString())); + currentStringBuilder = null; + } + signatureSteps.Add(new RuntimeGenericSignatureStep(typeParameter, localTypeParameter)); + } + + public void PushCustomSignature(MethodReference customSignatureMethod) + { + if (currentStringBuilder is not null) + { + signatureSteps.Add(new StringStep(currentStringBuilder.ToString())); + currentStringBuilder = null; + } + signatureSteps.Add(new RuntimeCustomSignatureStep(customSignatureMethod)); + } + + public void EmitGuidGetter( + TypeDefinition guidDataBlockType, + TypeDefinition implementationDetailsType, + TypeReference readOnlySpanofByte, + MethodReference readOnlySpanOfByteCtor, + TypeDefinition guidGeneratorType) + { + if (currentStringBuilder is not null) + { + signatureSteps.Add(new StringStep(currentStringBuilder.ToString())); + currentStringBuilder = null; + } + + // TODO: Emit IID Generation. + if (signatureSteps.Count == 1 && signatureSteps[0] is StringStep str) + { + GenerateGuidFromSimpleSignature(str, guidDataBlockType, implementationDetailsType, readOnlySpanofByte, readOnlySpanOfByteCtor); + } + else + { + GenerateGuidFactoryFromComplexSignature(implementationDetailsType, readOnlySpanofByte, readOnlySpanOfByteCtor, guidGeneratorType); + } + } + + private void GenerateGuidFromSimpleSignature(StringStep stringStep, TypeDefinition guidDataBlockType, TypeDefinition implementationDetailsType, TypeReference readOnlySpanOfByte, MethodReference readOnlySpanOfByteCtor) + { + var maxBytes = Encoding.UTF8.GetMaxByteCount(stringStep.StaticSignatureString.Length); + + Span data = new byte[Unsafe.SizeOf() + maxBytes]; + WinRTPinterfaceNamespace.TryWriteBytes(data); + var numBytes = Encoding.UTF8.GetBytes(stringStep.StaticSignatureString, data[Unsafe.SizeOf()..]); + data = data[..(Unsafe.SizeOf() + numBytes)]; + + Debug.Assert(SHA1.Create().HashSize == 160); + + Span hash = stackalloc byte[160]; + SHA1.HashData(data, hash); + + // Encode rfc time/version/clock/reserved fields + hash[8] = (byte)((hash[8] & 0x3f) | 0x80); + + var iid = new Guid( + BinaryPrimitives.ReadInt32BigEndian(hash[0..4]), + BinaryPrimitives.ReadInt16BigEndian(hash[4..6]), + (short)((BinaryPrimitives.ReadInt16BigEndian(hash[6..8]) & 0xff0f) | (5 << 4)), + hash[8..16].ToArray()); + + CecilExtensions.WriteIIDDataGetterBody(guidDataGetterMethod, describedType, iid, guidDataBlockType, implementationDetailsType, readOnlySpanOfByteCtor); + } + + private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementationDetailsType, TypeReference readOnlySpanOfByte, MethodReference readOnlySpanOfBytePtrCtor, TypeDefinition guidGeneratorType) + { + var module = implementationDetailsType.Module; + + var readOnlySpanOfByteArrayCtor = module.ImportReference( + new MethodReference(".ctor", module.TypeSystem.Void, readOnlySpanOfByte) + { + Parameters = { new ParameterDefinition(new ArrayType(readOnlySpanOfByte.Resolve().GenericParameters[0])) } + }, + readOnlySpanOfByte); + + // Create generic class with static array field to cache result. + var cacheType = new TypeDefinition(null, $"{describedType.FullName}", TypeAttributes.NestedPrivate | TypeAttributes.Abstract | TypeAttributes.Sealed, module.ImportReference(module.TypeSystem.Object)); + + for (int i = 0; i < guidDataGetterMethod.GenericParameters.Count; i++) + { + cacheType.GenericParameters.Add(new GenericParameter(cacheType)); + } + + var instantiatedCacheType = new GenericInstanceType(cacheType); + foreach (var arg in guidDataGetterMethod.GenericParameters) + { + instantiatedCacheType.GenericArguments.Add(arg); + } + + var selfInstantiatedCacheType = new GenericInstanceType(cacheType); + foreach (var param in cacheType.GenericParameters) + { + selfInstantiatedCacheType.GenericArguments.Add(param); + } + + var cacheField = new FieldDefinition("iidData", FieldAttributes.Static | FieldAttributes.Assembly, new ArrayType(module.ImportReference(module.TypeSystem.Byte))); + cacheType.Fields.Add(cacheField); + implementationDetailsType.NestedTypes.Add(cacheType); + + var staticCtor = new MethodDefinition(".cctor", MethodAttributes.Static | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName | MethodAttributes.Private, module.TypeSystem.Void); + + cacheType.Methods.Add(staticCtor); + + // In the body of the getter method, return the cache data + var getterIL = guidDataGetterMethod.Body.GetILProcessor(); + getterIL.Emit(OpCodes.Ldsfld, new FieldReference(cacheField.Name, cacheField.FieldType, instantiatedCacheType)); + getterIL.Emit(OpCodes.Newobj, readOnlySpanOfByteArrayCtor); + getterIL.Emit(OpCodes.Ret); + + // In the static constructor, calculate the guid bytes. + var il = staticCtor.Body.GetILProcessor(); + var signatureParts = new VariableDefinition[signatureSteps.Count]; + + var systemType = module.ImportReference( + new TypeReference("System", "Type", module, module.TypeSystem.CoreLibrary)); + + var getTypeFromHandleMethod = module.ImportReference(systemType.Resolve().Methods.First(m => m.Name == "GetTypeFromHandle")); + var getSignatureMethod = module.ImportReference( + new MethodReference("GetSignature", module.TypeSystem.String, guidGeneratorType) + { + Parameters = { new ParameterDefinition(systemType) }, + HasThis = false + }); + + var encodingType = CecilExtensions.FindTypeReference(module, "System.Text", "Encoding", "System.Runtime", false)!; + var utf8EncodingGetter = module.ImportReference(new MethodReference("get_UTF8", encodingType, encodingType)); + var encodingGetBytes = module.ImportReference( + new MethodReference("GetBytes", new ArrayType(module.TypeSystem.Byte), encodingType) + { + Parameters = { new ParameterDefinition(module.TypeSystem.String) } + }); + + var fullSignatureLength = new VariableDefinition(module.TypeSystem.Int32); + staticCtor.Body.Variables.Add(fullSignatureLength); + il.Emit(OpCodes.Ldc_I4, 16); + il.Emit(OpCodes.Stloc, fullSignatureLength); + + for (int i = 0; i < signatureSteps.Count; i++) + { + signatureParts[i] = new VariableDefinition(readOnlySpanOfByte); + staticCtor.Body.Variables.Add(signatureParts[i]); + switch (signatureSteps[i]) + { + case StringStep(string str): + { + byte[] segmentBytes = Encoding.UTF8.GetBytes(str); + var staticDataField = new FieldDefinition($"", FieldAttributes.Private | FieldAttributes.InitOnly | FieldAttributes.Static | FieldAttributes.HasFieldRVA, CecilExtensions.GetOrCreateDataBlockType(implementationDetailsType, segmentBytes.Length)) + { + InitialValue = segmentBytes + }; + cacheType.Fields.Add(staticDataField); + + // Load a ReadOnlySpan of the signature segment into the local for this step. + il.Emit(OpCodes.Ldsflda, new FieldReference(staticDataField.Name, staticDataField.FieldType, selfInstantiatedCacheType)); + il.Emit(OpCodes.Ldc_I4, segmentBytes.Length); + il.Emit(OpCodes.Newobj, readOnlySpanOfBytePtrCtor); + il.Emit(OpCodes.Stloc, signatureParts[i]); + // signatureLength += staticData.Length + il.Emit(OpCodes.Ldloc, fullSignatureLength); + il.Emit(OpCodes.Ldc_I4, segmentBytes.Length); + il.Emit(OpCodes.Add_Ovf); + il.Emit(OpCodes.Stloc, fullSignatureLength); + } + break; + case RuntimeGenericSignatureStep(_, GenericParameter localTypeParameter): + { + // byte[] bytes = Encoding.UTF8.GetBytes(GetSignature(typeof(localTypeParameter))) + il.Emit(OpCodes.Call, utf8EncodingGetter); + il.Emit(OpCodes.Ldtoken, localTypeParameter); + il.Emit(OpCodes.Call, getTypeFromHandleMethod); + il.Emit(OpCodes.Call, getSignatureMethod); + il.Emit(OpCodes.Callvirt, encodingGetBytes); + il.Emit(OpCodes.Dup); + // = new ReadOnlySpan(bytes); + il.Emit(OpCodes.Newobj, readOnlySpanOfByteArrayCtor); + il.Emit(OpCodes.Stloc, signatureParts[i]); + // signatureLength += bytes.Length + il.Emit(OpCodes.Ldlen); + il.Emit(OpCodes.Ldloc, fullSignatureLength); + il.Emit(OpCodes.Add_Ovf); + il.Emit(OpCodes.Stloc, fullSignatureLength); + } + break; + case RuntimeCustomSignatureStep(MethodReference customSignatureMethod): + { + // byte[] bytes = Encoding.UTF8.GetBytes(customSignatureMethod()) + il.Emit(OpCodes.Call, utf8EncodingGetter); + il.Emit(OpCodes.Call, customSignatureMethod); + il.Emit(OpCodes.Callvirt, encodingGetBytes); + il.Emit(OpCodes.Dup); + // = new ReadOnlySpan(bytes); + il.Emit(OpCodes.Newobj, readOnlySpanOfByteArrayCtor); + il.Emit(OpCodes.Stloc, signatureParts[i]); + // signatureLength += bytes.Length + il.Emit(OpCodes.Ldlen); + il.Emit(OpCodes.Ldloc, fullSignatureLength); + il.Emit(OpCodes.Add_Ovf); + il.Emit(OpCodes.Stloc, fullSignatureLength); + } + break; + default: + il.Clear(); + throw new InvalidOperationException(); + } + } + + var span = CecilExtensions.FindTypeReference(module, "System", "Span`1", "System.Runtime", true); + + if (span is null) + { + throw new InvalidOperationException(); + } + + var spanOfByte = new GenericInstanceType(span) + { + GenericArguments = { module.ImportReference(module.TypeSystem.Byte) } + }; + + var spanOfBytePtrCtor = module.ImportReference(new MethodReference(".ctor", module.TypeSystem.Void, spanOfByte) + { + Parameters = + { + new ParameterDefinition(new PointerType(module.TypeSystem.Void)), + new ParameterDefinition(module.TypeSystem.Int32), + } + }); + + var spanOfByteArrayCtor = module.ImportReference( + new MethodReference(".ctor", module.TypeSystem.Void, spanOfByte) + { + Parameters = { new ParameterDefinition(new ArrayType(span.Resolve().GenericParameters[0])) } + }, + spanOfByte); + + var copyToMethod = module.ImportReference( + new MethodReference("CopyTo", module.TypeSystem.Void, readOnlySpanOfByte) + { + Parameters = + { + new ParameterDefinition( + module.ImportReference(new GenericInstanceType(span) { GenericArguments = { readOnlySpanOfByte.Resolve().GenericParameters[0] } })) + } + }); + + var spanSliceStartMethod = module.ImportReference( + new MethodReference("Slice", spanOfByte, spanOfByte) + { + HasThis = true, + Parameters = { new ParameterDefinition(module.TypeSystem.Int32) } + }); + + var spanSliceStartLengthMethod = module.ImportReference( + new MethodReference("Slice", spanOfByte, spanOfByte) + { + HasThis = true, + Parameters = { new ParameterDefinition(module.TypeSystem.Int32), new ParameterDefinition(module.TypeSystem.Int32) } + }); + + var readOnlySpanOfByteLength = module.ImportReference(new MethodReference("get_Length", module.TypeSystem.Int32, readOnlySpanOfByte)); + + var fullSignatureBuffer = new VariableDefinition(spanOfByte); + staticCtor.Body.Variables.Add(fullSignatureBuffer); + + // fullSignatureBuffer = new Span(new byte[fullSignatureLength]); + il.Emit(OpCodes.Ldloc, fullSignatureLength); + il.Emit(OpCodes.Newarr, module.ImportReference(module.TypeSystem.Byte)); + il.Emit(OpCodes.Newobj, spanOfByteArrayCtor); + il.Emit(OpCodes.Stloc, fullSignatureBuffer); + + // Write WinRTPinterfaceNamespace bytes to the buffer + const string WinRTPinterfaceDataBlockName = ""; + + var staticNamespaceBytesField = new FieldReference(WinRTPinterfaceDataBlockName, CecilExtensions.GetOrCreateDataBlockType(implementationDetailsType, 16), implementationDetailsType); + + if (staticNamespaceBytesField.Resolve() is null) + { + staticNamespaceBytesField = new FieldDefinition(WinRTPinterfaceDataBlockName, FieldAttributes.Static | FieldAttributes.Assembly | FieldAttributes.InitOnly | FieldAttributes.HasFieldRVA, CecilExtensions.GetOrCreateDataBlockType(implementationDetailsType, 16)) + { + InitialValue = WinRTPinterfaceNamespace.ToByteArray() + }; + + implementationDetailsType.Fields.Add((FieldDefinition)staticNamespaceBytesField); + } + + il.Emit(OpCodes.Ldsflda, staticNamespaceBytesField); + il.Emit(OpCodes.Ldc_I4, 16); + var readOnlySpanTemp = new VariableDefinition(readOnlySpanOfByte); + staticCtor.Body.Variables.Add(readOnlySpanTemp); + il.Emit(OpCodes.Newobj, readOnlySpanOfBytePtrCtor); + il.Emit(OpCodes.Stloc, readOnlySpanTemp); + il.Emit(OpCodes.Ldloca, readOnlySpanTemp); + il.Emit(OpCodes.Ldloc, fullSignatureBuffer); + il.Emit(OpCodes.Call, copyToMethod); + + // int offset = 16; + var offset = new VariableDefinition(module.TypeSystem.Int32); + staticCtor.Body.Variables.Add(offset); + il.Emit(OpCodes.Ldc_I4, 16); + il.Emit(OpCodes.Stloc, offset); + + for (int i = 0; i < signatureParts.Length; i++) + { + // locals[i].CopyTo(fullSignatureBuffer.Slice(offset)); + il.Emit(OpCodes.Ldloca, signatureParts[i]); + il.Emit(OpCodes.Dup); + il.Emit(OpCodes.Ldloca, fullSignatureBuffer); + il.Emit(OpCodes.Ldloc, offset); + il.Emit(OpCodes.Call, spanSliceStartMethod); + il.Emit(OpCodes.Call, copyToMethod); + // offset += locals[i].Length; + il.Emit(OpCodes.Call, readOnlySpanOfByteLength); + il.Emit(OpCodes.Ldloc, offset); + il.Emit(OpCodes.Add); + il.Emit(OpCodes.Stloc, offset); + } + + var destination = new VariableDefinition(spanOfByte); + staticCtor.Body.Variables.Add(destination); + + // Span destination = stackalloc byte[160]; + il.Emit(OpCodes.Ldc_I4, 160); + il.Emit(OpCodes.Localloc); + il.Emit(OpCodes.Ldc_I4, 160); + il.Emit(OpCodes.Newobj, spanOfBytePtrCtor); + il.Emit(OpCodes.Stloc, destination); + + // SHA1.HashData(fullSignatureBuffer, destination); + var sha1Type = CecilExtensions.FindTypeReference(module, "System.Security.Cryptography", "SHA1", "System.Security.Cryptography.Algorithms", false); + var hashDataMethod = module.ImportReference( + new MethodReference("HashData", module.ImportReference(module.TypeSystem.Int32), sha1Type) + { + HasThis = false, + Parameters = + { + new ParameterDefinition(readOnlySpanOfByte), + new ParameterDefinition(spanOfByte) + } + }); + + var spanToReadOnlySpan = module.ImportReference( + new MethodReference("op_Implicit", + new GenericInstanceType(module.ImportReference(readOnlySpanOfByte.Resolve())) + { + GenericArguments = { span.Resolve().GenericParameters[0] } + }, + spanOfByte) + { + HasThis = false, + Parameters = + { + new ParameterDefinition( + new GenericInstanceType(span) + { + GenericArguments = { span.Resolve().GenericParameters[0] } + }) + } + }); + + il.Emit(OpCodes.Ldloc, fullSignatureBuffer); + il.Emit(OpCodes.Call, spanToReadOnlySpan); + il.Emit(OpCodes.Ldloc, destination); + il.Emit(OpCodes.Call, hashDataMethod); + + // Fix endianness, bytes + var memoryExtensions = CecilExtensions.FindTypeReference(module, "System", "MemoryExtensions", "System.Memory", false); + var reverseMethod = new MethodReference("Reverse", module.TypeSystem.Void, memoryExtensions) + { + HasThis = false, + }; + var reverseMethodGenericParam = new GenericParameter(reverseMethod); + reverseMethod.GenericParameters.Add(reverseMethodGenericParam); + reverseMethod.Parameters.Add(new ParameterDefinition(new GenericInstanceType(span) { GenericArguments = { reverseMethodGenericParam } })); + reverseMethod = module.ImportReference( + new GenericInstanceMethod(reverseMethod) + { + GenericArguments = { module.TypeSystem.Byte } + }); + + // Filp endianness to little endian for the int/short components of the guid. + il.Emit(OpCodes.Ldloca, destination); + il.Emit(OpCodes.Ldc_I4_0); + il.Emit(OpCodes.Ldc_I4_4); + il.Emit(OpCodes.Call, spanSliceStartLengthMethod); + il.Emit(OpCodes.Call, reverseMethod); + il.Emit(OpCodes.Ldloca, destination); + il.Emit(OpCodes.Ldc_I4_4); + il.Emit(OpCodes.Ldc_I4_2); + il.Emit(OpCodes.Call, spanSliceStartLengthMethod); + il.Emit(OpCodes.Call, reverseMethod); + il.Emit(OpCodes.Ldloca, destination); + il.Emit(OpCodes.Ldc_I4_6); + il.Emit(OpCodes.Ldc_I4_2); + il.Emit(OpCodes.Call, spanSliceStartLengthMethod); + il.Emit(OpCodes.Call, reverseMethod); + + // Encode rfc time/version/clock/reserved fields + var getItemMethod = module.ImportReference(new MethodReference("get_Item", new ByReferenceType(span.Resolve().GenericParameters[0]), spanOfByte) { Parameters = { new ParameterDefinition(module.TypeSystem.Int32) } }); + + // t[7] = (byte) ((t[7] & 0x0f) | (5 << 4)); + il.Emit(OpCodes.Ldloca, destination); + il.Emit(OpCodes.Ldc_I4_7); + il.Emit(OpCodes.Call, getItemMethod); + il.Emit(OpCodes.Dup); + il.Emit(OpCodes.Ldind_U1); + il.Emit(OpCodes.Ldc_I4, 0x0f); + il.Emit(OpCodes.And); + il.Emit(OpCodes.Ldc_I4, 5 << 4); + il.Emit(OpCodes.Or); + il.Emit(OpCodes.Conv_U1); + il.Emit(OpCodes.Stind_I1); + + // t[8] = (byte)((t[8] & 0x3f) | 0x80); + il.Emit(OpCodes.Ldloca, destination); + il.Emit(OpCodes.Ldc_I4_8); + il.Emit(OpCodes.Call, getItemMethod); + il.Emit(OpCodes.Dup); + il.Emit(OpCodes.Ldind_U1); + il.Emit(OpCodes.Ldc_I4, 0x3f); + il.Emit(OpCodes.And); + il.Emit(OpCodes.Ldc_I4, 0x80); + il.Emit(OpCodes.Or); + il.Emit(OpCodes.Conv_U1); + il.Emit(OpCodes.Stind_I1); + + // cacheField = destination.Slice(0, 16).ToArray() + + var toArrayMethod = module.ImportReference(new MethodReference("ToArray", new ArrayType(span.Resolve().GenericParameters[0]), spanOfByte)); + var spanTemp = new VariableDefinition(spanOfByte); + staticCtor.Body.Variables.Add(spanTemp); + + il.Emit(OpCodes.Ldloca, destination); + il.Emit(OpCodes.Ldc_I4_0); + il.Emit(OpCodes.Ldc_I4, 16); + il.Emit(OpCodes.Call, spanSliceStartLengthMethod); + il.Emit(OpCodes.Stloc, spanTemp); + il.Emit(OpCodes.Ldloca, spanTemp); + il.Emit(OpCodes.Call, toArrayMethod); + il.Emit(OpCodes.Stsfld, new FieldReference(cacheField.Name, cacheField.FieldType, selfInstantiatedCacheType)); + il.Emit(OpCodes.Ret); + } + } +} diff --git a/src/Perf/GuidPatch/SignatureGenerator.cs b/src/Perf/GuidPatch/SignatureGenerator.cs new file mode 100644 index 000000000..4eac5e14a --- /dev/null +++ b/src/Perf/GuidPatch/SignatureGenerator.cs @@ -0,0 +1,212 @@ +using Mono.Cecil; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; + +namespace GuidPatch +{ + abstract record SignaturePart; + + enum SignatureType + { + i1, + u1, + i2, + u2, + i4, + u4, + i8, + u8, + f4, + f8, + b1, + c2, + g16, + @string, + iinspectable + } + + record BasicSignaturePart(SignatureType Type) : SignaturePart; + + abstract record SignatureWithChildren(string GroupingName, string ThisEntitySignature, IEnumerable ChildrenSignatures) : SignaturePart; + + sealed record GenericSignature(Guid BaseGuid, IEnumerable GenericMemberSignatures) : SignatureWithChildren("pinterface", BaseGuid.ToString("B"), GenericMemberSignatures); + + sealed record ValueTypeSignature(TypeReference Type, IEnumerable StructFieldSignatures) : SignatureWithChildren("struct", Type.FullName, StructFieldSignatures); + + sealed record RuntimeClassSignature(TypeReference RuntimeClass, SignaturePart DefaultInterfaceSignature) : SignatureWithChildren("rc", RuntimeClass.FullName, new[] { DefaultInterfaceSignature }); + + sealed record EnumSignature(TypeReference Type, bool IsFlagEnum) : SignatureWithChildren("enum", Type.FullName, new SignaturePart[] { new BasicSignaturePart(IsFlagEnum ? SignatureType.u4 : SignatureType.i4) }); + + sealed record NonGenericDelegateSignature(Guid DelegateIID) : SignaturePart; + + sealed record GuidSignature(Guid IID) : SignaturePart; + + sealed record UninstantiatedGeneric(GenericParameter OriginalGenericParameter) : SignaturePart; + + sealed record CustomSignatureMethod(MethodReference Method) : SignaturePart; + + sealed class SignatureGenerator + { + private readonly AssemblyDefinition assembly; + private readonly TypeDefinition guidAttributeType; + private readonly AssemblyDefinition winRTRuntimeAssembly; + + public SignatureGenerator(AssemblyDefinition assembly, TypeDefinition guidAttributeType, AssemblyDefinition winRTRuntimeAssembly) + { + this.assembly = assembly; + this.guidAttributeType = guidAttributeType; + this.winRTRuntimeAssembly = winRTRuntimeAssembly; + } + + public SignaturePart GetSignatureParts(TypeReference type) + { + if (type.IsGenericParameter) + { + return new UninstantiatedGeneric((GenericParameter)type); + } + + var typeDef = type.Resolve(); + + var helperType = new TypeReference($"ABI.{typeDef.Namespace}", typeDef.Name, assembly.MainModule, typeDef.Module); + + if (helperType.Resolve() is not null) + { + if (type.IsGenericInstance) + { + var helperTypeGeneric = new GenericInstanceType(helperType); + foreach (var arg in ((GenericInstanceType)type).GenericArguments) + { + helperTypeGeneric.GenericArguments.Add(arg); + } + helperType = helperTypeGeneric; + } + + var getGuidSignatureMethod = new MethodReference("GetGuidSignature", assembly.MainModule.TypeSystem.String, helperType) + { + HasThis = false + }; + + if (getGuidSignatureMethod.Resolve() is not null) + { + return new CustomSignatureMethod(assembly.MainModule.ImportReference(getGuidSignatureMethod)); + } + } + + type = typeDef.IsInterface ? (CreateAuthoringMetadataTypeReference(type).Resolve() ?? type) : type; + if (typeDef == assembly.MainModule.TypeSystem.Object.Resolve()) + { + return new BasicSignaturePart(SignatureType.iinspectable); + } + + if (type.IsGenericInstance) + { + List signatureParts = new(); + + foreach (var arg in ((GenericInstanceType)type).GenericArguments) + { + signatureParts.Add(GetSignatureParts(arg)); + } + + Guid? baseGuid = type.ReadGuidFromAttribute(guidAttributeType, winRTRuntimeAssembly); + if (baseGuid == null) + { + throw new InvalidOperationException(); + } + return new GenericSignature(baseGuid.Value, signatureParts); + } + + if (type.IsValueType) + { + switch (type.Name) + { + case "SByte": return new BasicSignaturePart(SignatureType.i1); + case "Byte": return new BasicSignaturePart(SignatureType.u1); + case "Int16": return new BasicSignaturePart(SignatureType.i2); + case "UInt16": return new BasicSignaturePart(SignatureType.u2); + case "Int32": return new BasicSignaturePart(SignatureType.i4); + case "UInt32": return new BasicSignaturePart(SignatureType.u4); + case "Int64": return new BasicSignaturePart(SignatureType.i8); + case "UInt64": return new BasicSignaturePart(SignatureType.u8); + case "Single": return new BasicSignaturePart(SignatureType.f4); + case "Double": return new BasicSignaturePart(SignatureType.f8); + case "Boolean": return new BasicSignaturePart(SignatureType.b1); + case "Char": return new BasicSignaturePart(SignatureType.c2); + case "Guid": return new BasicSignaturePart(SignatureType.g16); + default: + { + if (typeDef.IsEnum) + { + var isFlags = typeDef.CustomAttributes.Any(cad => cad.AttributeType.Name == "FlagsAttribute"); + return new EnumSignature(type, isFlags); + } + if (!type.IsPrimitive) + { + var args = type.Resolve().Fields.Where(f => f.IsPublic && !f.IsStatic).Select(fi => + GetSignatureParts( + assembly.MainModule.ImportReference(new FieldReference(fi.Name, fi.FieldType, type)).FieldType)).ToArray(); + return new ValueTypeSignature(type, args); + } + throw new InvalidOperationException("unsupported value type"); + } + } + } + + if (typeDef == assembly.MainModule.TypeSystem.String.Resolve()) + { + return new BasicSignaturePart(SignatureType.@string); + } + + if (TryGetDefaultInterfaceTypeForRuntimeClassType(type, out TypeReference? iface)) + { + return new RuntimeClassSignature(type, GetSignatureParts(iface)); + } + + Guid? guidAttributeValue = type.ReadGuidFromAttribute(guidAttributeType, winRTRuntimeAssembly); + if (guidAttributeValue == null) + { + throw new InvalidOperationException($"Unable to read IID attribute value for {type.FullName}."); + } + + if (typeDef.BaseType?.Name == "MulticastDelegate") + { + return new NonGenericDelegateSignature(guidAttributeValue.Value); + } + + return new GuidSignature(guidAttributeValue.Value); + } + + private TypeReference CreateAuthoringMetadataTypeReference(TypeReference type) + { + return new TypeReference($"ABI.Impl.{type.Name}", type.Name, assembly.MainModule, type.Module); + } + + bool TryGetDefaultInterfaceTypeForRuntimeClassType(TypeReference runtimeClassTypeMaybe, [NotNullWhen(true)] out TypeReference? defaultInterface) + { + defaultInterface = null; + + TypeDefinition rcDef = runtimeClassTypeMaybe.Resolve(); + rcDef = CreateAuthoringMetadataTypeReference(rcDef).Resolve() ?? rcDef; + + CustomAttribute? runtimeClassAttribute = rcDef.CustomAttributes.FirstOrDefault(ca => ca.AttributeType.Namespace == "WinRT" && ca.AttributeType.Name == "ProjectedRuntimeClassAttribute"); + + if (runtimeClassAttribute is null) + { + return false; + } + + string defaultInterfacePropertyName = (string)runtimeClassAttribute.ConstructorArguments[0].Value; + + var defaultInterfaceProperty = rcDef.Properties.FirstOrDefault(prop => prop.Name == defaultInterfacePropertyName); + + if (defaultInterfaceProperty is null) + { + return false; + } + + defaultInterface = defaultInterfaceProperty.PropertyType; + return true; + } + } +} diff --git a/src/cswinrt.sln b/src/cswinrt.sln index 9197abf9a..b28214168 100644 --- a/src/cswinrt.sln +++ b/src/cswinrt.sln @@ -99,208 +99,282 @@ Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "AuthoringWinUITest (Package EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AuthoringWinUITest", "Tests\AuthoringWinUITest\AuthoringWinUITest\AuthoringWinUITest.vcxproj", "{493C7729-2F21-4198-AB09-BDF56BF501D3}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Perf", "Perf", "{539DBDEF-3B49-4503-9BD3-7EB83C2179CB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GuidPatch", "Perf\GuidPatch\GuidPatch.csproj", "{AE3B0611-2FBB-42AB-A245-B4E79868A5F9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7E3A9AB3-8CBB-4B9C-BA76-0FE7108DCAEB}.Debug|Any CPU.ActiveCfg = Debug|Win32 {7E3A9AB3-8CBB-4B9C-BA76-0FE7108DCAEB}.Debug|x64.ActiveCfg = Debug|x64 {7E3A9AB3-8CBB-4B9C-BA76-0FE7108DCAEB}.Debug|x64.Build.0 = Debug|x64 {7E3A9AB3-8CBB-4B9C-BA76-0FE7108DCAEB}.Debug|x86.ActiveCfg = Debug|Win32 {7E3A9AB3-8CBB-4B9C-BA76-0FE7108DCAEB}.Debug|x86.Build.0 = Debug|Win32 + {7E3A9AB3-8CBB-4B9C-BA76-0FE7108DCAEB}.Release|Any CPU.ActiveCfg = Release|Win32 {7E3A9AB3-8CBB-4B9C-BA76-0FE7108DCAEB}.Release|x64.ActiveCfg = Release|x64 {7E3A9AB3-8CBB-4B9C-BA76-0FE7108DCAEB}.Release|x64.Build.0 = Release|x64 {7E3A9AB3-8CBB-4B9C-BA76-0FE7108DCAEB}.Release|x86.ActiveCfg = Release|Win32 {7E3A9AB3-8CBB-4B9C-BA76-0FE7108DCAEB}.Release|x86.Build.0 = Release|Win32 + {9A9F52CA-F624-43A4-B5EF-C50861F584C2}.Debug|Any CPU.ActiveCfg = Debug|x86 {9A9F52CA-F624-43A4-B5EF-C50861F584C2}.Debug|x64.ActiveCfg = Debug|x64 {9A9F52CA-F624-43A4-B5EF-C50861F584C2}.Debug|x64.Build.0 = Debug|x64 {9A9F52CA-F624-43A4-B5EF-C50861F584C2}.Debug|x86.ActiveCfg = Debug|x86 {9A9F52CA-F624-43A4-B5EF-C50861F584C2}.Debug|x86.Build.0 = Debug|x86 + {9A9F52CA-F624-43A4-B5EF-C50861F584C2}.Release|Any CPU.ActiveCfg = Release|x86 {9A9F52CA-F624-43A4-B5EF-C50861F584C2}.Release|x64.ActiveCfg = Release|x64 {9A9F52CA-F624-43A4-B5EF-C50861F584C2}.Release|x64.Build.0 = Release|x64 {9A9F52CA-F624-43A4-B5EF-C50861F584C2}.Release|x86.ActiveCfg = Release|x86 {9A9F52CA-F624-43A4-B5EF-C50861F584C2}.Release|x86.Build.0 = Release|x86 + {6ACFD2B2-E8AA-4CD4-AAD8-213CE8BB2637}.Debug|Any CPU.ActiveCfg = Debug|Win32 {6ACFD2B2-E8AA-4CD4-AAD8-213CE8BB2637}.Debug|x64.ActiveCfg = Debug|x64 {6ACFD2B2-E8AA-4CD4-AAD8-213CE8BB2637}.Debug|x64.Build.0 = Debug|x64 {6ACFD2B2-E8AA-4CD4-AAD8-213CE8BB2637}.Debug|x86.ActiveCfg = Debug|Win32 {6ACFD2B2-E8AA-4CD4-AAD8-213CE8BB2637}.Debug|x86.Build.0 = Debug|Win32 + {6ACFD2B2-E8AA-4CD4-AAD8-213CE8BB2637}.Release|Any CPU.ActiveCfg = Release|Win32 {6ACFD2B2-E8AA-4CD4-AAD8-213CE8BB2637}.Release|x64.ActiveCfg = Release|x64 {6ACFD2B2-E8AA-4CD4-AAD8-213CE8BB2637}.Release|x64.Build.0 = Release|x64 {6ACFD2B2-E8AA-4CD4-AAD8-213CE8BB2637}.Release|x86.ActiveCfg = Release|Win32 {6ACFD2B2-E8AA-4CD4-AAD8-213CE8BB2637}.Release|x86.Build.0 = Release|Win32 + {2954F343-85A7-46F5-A3F3-F106FDD13900}.Debug|Any CPU.ActiveCfg = Debug|Win32 {2954F343-85A7-46F5-A3F3-F106FDD13900}.Debug|x64.ActiveCfg = Debug|x64 {2954F343-85A7-46F5-A3F3-F106FDD13900}.Debug|x64.Build.0 = Debug|x64 {2954F343-85A7-46F5-A3F3-F106FDD13900}.Debug|x86.ActiveCfg = Debug|Win32 {2954F343-85A7-46F5-A3F3-F106FDD13900}.Debug|x86.Build.0 = Debug|Win32 + {2954F343-85A7-46F5-A3F3-F106FDD13900}.Release|Any CPU.ActiveCfg = Release|Win32 {2954F343-85A7-46F5-A3F3-F106FDD13900}.Release|x64.ActiveCfg = Release|x64 {2954F343-85A7-46F5-A3F3-F106FDD13900}.Release|x64.Build.0 = Release|x64 {2954F343-85A7-46F5-A3F3-F106FDD13900}.Release|x86.ActiveCfg = Release|Win32 {2954F343-85A7-46F5-A3F3-F106FDD13900}.Release|x86.Build.0 = Release|Win32 + {25244CED-966E-45F2-9711-1F51E951FF89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {25244CED-966E-45F2-9711-1F51E951FF89}.Debug|Any CPU.Build.0 = Debug|Any CPU {25244CED-966E-45F2-9711-1F51E951FF89}.Debug|x64.ActiveCfg = Debug|Any CPU {25244CED-966E-45F2-9711-1F51E951FF89}.Debug|x64.Build.0 = Debug|Any CPU {25244CED-966E-45F2-9711-1F51E951FF89}.Debug|x86.ActiveCfg = Debug|Any CPU {25244CED-966E-45F2-9711-1F51E951FF89}.Debug|x86.Build.0 = Debug|Any CPU + {25244CED-966E-45F2-9711-1F51E951FF89}.Release|Any CPU.ActiveCfg = Release|Any CPU + {25244CED-966E-45F2-9711-1F51E951FF89}.Release|Any CPU.Build.0 = Release|Any CPU {25244CED-966E-45F2-9711-1F51E951FF89}.Release|x64.ActiveCfg = Release|Any CPU {25244CED-966E-45F2-9711-1F51E951FF89}.Release|x64.Build.0 = Release|Any CPU {25244CED-966E-45F2-9711-1F51E951FF89}.Release|x86.ActiveCfg = Release|Any CPU {25244CED-966E-45F2-9711-1F51E951FF89}.Release|x86.Build.0 = Release|Any CPU + {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Debug|Any CPU.ActiveCfg = Debug|x86 {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Debug|x64.ActiveCfg = Debug|x64 {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Debug|x64.Build.0 = Debug|x64 {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Debug|x86.ActiveCfg = Debug|x86 {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Debug|x86.Build.0 = Debug|x86 + {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Release|Any CPU.ActiveCfg = Release|x86 {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Release|x64.ActiveCfg = Release|x64 {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Release|x64.Build.0 = Release|x64 {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Release|x86.ActiveCfg = Release|x86 {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Release|x86.Build.0 = Release|x86 + {C6D580C5-7037-4733-B933-916FF400AFE2}.Debug|Any CPU.ActiveCfg = Debug|x86 {C6D580C5-7037-4733-B933-916FF400AFE2}.Debug|x64.ActiveCfg = Debug|x64 {C6D580C5-7037-4733-B933-916FF400AFE2}.Debug|x64.Build.0 = Debug|x64 {C6D580C5-7037-4733-B933-916FF400AFE2}.Debug|x86.ActiveCfg = Debug|x86 {C6D580C5-7037-4733-B933-916FF400AFE2}.Debug|x86.Build.0 = Debug|x86 + {C6D580C5-7037-4733-B933-916FF400AFE2}.Release|Any CPU.ActiveCfg = Release|x86 {C6D580C5-7037-4733-B933-916FF400AFE2}.Release|x64.ActiveCfg = Release|x64 {C6D580C5-7037-4733-B933-916FF400AFE2}.Release|x64.Build.0 = Release|x64 {C6D580C5-7037-4733-B933-916FF400AFE2}.Release|x86.ActiveCfg = Release|x86 {C6D580C5-7037-4733-B933-916FF400AFE2}.Release|x86.Build.0 = Release|x86 + {FFA9A78B-F53F-43EE-AF87-24A80F4C330A}.Debug|Any CPU.ActiveCfg = Debug|x86 {FFA9A78B-F53F-43EE-AF87-24A80F4C330A}.Debug|x64.ActiveCfg = Debug|x64 {FFA9A78B-F53F-43EE-AF87-24A80F4C330A}.Debug|x64.Build.0 = Debug|x64 {FFA9A78B-F53F-43EE-AF87-24A80F4C330A}.Debug|x86.ActiveCfg = Debug|x86 {FFA9A78B-F53F-43EE-AF87-24A80F4C330A}.Debug|x86.Build.0 = Debug|x86 + {FFA9A78B-F53F-43EE-AF87-24A80F4C330A}.Release|Any CPU.ActiveCfg = Release|x86 {FFA9A78B-F53F-43EE-AF87-24A80F4C330A}.Release|x64.ActiveCfg = Release|x64 {FFA9A78B-F53F-43EE-AF87-24A80F4C330A}.Release|x64.Build.0 = Release|x64 {FFA9A78B-F53F-43EE-AF87-24A80F4C330A}.Release|x86.ActiveCfg = Release|x86 {FFA9A78B-F53F-43EE-AF87-24A80F4C330A}.Release|x86.Build.0 = Release|x86 + {0A991D5F-BFEE-4D2F-9AAD-6AD06470A5DF}.Debug|Any CPU.ActiveCfg = Debug|x86 {0A991D5F-BFEE-4D2F-9AAD-6AD06470A5DF}.Debug|x64.ActiveCfg = Debug|x64 {0A991D5F-BFEE-4D2F-9AAD-6AD06470A5DF}.Debug|x64.Build.0 = Debug|x64 {0A991D5F-BFEE-4D2F-9AAD-6AD06470A5DF}.Debug|x86.ActiveCfg = Debug|x86 {0A991D5F-BFEE-4D2F-9AAD-6AD06470A5DF}.Debug|x86.Build.0 = Debug|x86 + {0A991D5F-BFEE-4D2F-9AAD-6AD06470A5DF}.Release|Any CPU.ActiveCfg = Release|x86 {0A991D5F-BFEE-4D2F-9AAD-6AD06470A5DF}.Release|x64.ActiveCfg = Release|x64 {0A991D5F-BFEE-4D2F-9AAD-6AD06470A5DF}.Release|x64.Build.0 = Release|x64 {0A991D5F-BFEE-4D2F-9AAD-6AD06470A5DF}.Release|x86.ActiveCfg = Release|x86 {0A991D5F-BFEE-4D2F-9AAD-6AD06470A5DF}.Release|x86.Build.0 = Release|x86 + {B34C96F4-3660-4B2D-8ABD-A4B428166DC7}.Debug|Any CPU.ActiveCfg = Debug|x86 {B34C96F4-3660-4B2D-8ABD-A4B428166DC7}.Debug|x64.ActiveCfg = Debug|x64 {B34C96F4-3660-4B2D-8ABD-A4B428166DC7}.Debug|x64.Build.0 = Debug|x64 {B34C96F4-3660-4B2D-8ABD-A4B428166DC7}.Debug|x86.ActiveCfg = Debug|x86 + {B34C96F4-3660-4B2D-8ABD-A4B428166DC7}.Release|Any CPU.ActiveCfg = Release|x86 {B34C96F4-3660-4B2D-8ABD-A4B428166DC7}.Release|x64.ActiveCfg = Release|x64 {B34C96F4-3660-4B2D-8ABD-A4B428166DC7}.Release|x64.Build.0 = Release|x64 {B34C96F4-3660-4B2D-8ABD-A4B428166DC7}.Release|x86.ActiveCfg = Release|x86 + {78D85F23-7CB1-44A1-9238-6DF2C76754E4}.Debug|Any CPU.ActiveCfg = Debug|Win32 {78D85F23-7CB1-44A1-9238-6DF2C76754E4}.Debug|x64.ActiveCfg = Debug|x64 {78D85F23-7CB1-44A1-9238-6DF2C76754E4}.Debug|x64.Build.0 = Debug|x64 {78D85F23-7CB1-44A1-9238-6DF2C76754E4}.Debug|x86.ActiveCfg = Debug|Win32 {78D85F23-7CB1-44A1-9238-6DF2C76754E4}.Debug|x86.Build.0 = Debug|Win32 + {78D85F23-7CB1-44A1-9238-6DF2C76754E4}.Release|Any CPU.ActiveCfg = Release|Win32 {78D85F23-7CB1-44A1-9238-6DF2C76754E4}.Release|x64.ActiveCfg = Release|x64 {78D85F23-7CB1-44A1-9238-6DF2C76754E4}.Release|x64.Build.0 = Release|x64 {78D85F23-7CB1-44A1-9238-6DF2C76754E4}.Release|x86.ActiveCfg = Release|Win32 {78D85F23-7CB1-44A1-9238-6DF2C76754E4}.Release|x86.Build.0 = Release|Win32 + {03EEF460-2F10-4FBE-AFFA-53477D3FC8D5}.Debug|Any CPU.ActiveCfg = Debug|x86 {03EEF460-2F10-4FBE-AFFA-53477D3FC8D5}.Debug|x64.ActiveCfg = Debug|x64 {03EEF460-2F10-4FBE-AFFA-53477D3FC8D5}.Debug|x64.Build.0 = Debug|x64 {03EEF460-2F10-4FBE-AFFA-53477D3FC8D5}.Debug|x86.ActiveCfg = Debug|x86 {03EEF460-2F10-4FBE-AFFA-53477D3FC8D5}.Debug|x86.Build.0 = Debug|x86 + {03EEF460-2F10-4FBE-AFFA-53477D3FC8D5}.Release|Any CPU.ActiveCfg = Release|x86 {03EEF460-2F10-4FBE-AFFA-53477D3FC8D5}.Release|x64.ActiveCfg = Release|x64 {03EEF460-2F10-4FBE-AFFA-53477D3FC8D5}.Release|x64.Build.0 = Release|x64 {03EEF460-2F10-4FBE-AFFA-53477D3FC8D5}.Release|x86.ActiveCfg = Release|x86 {03EEF460-2F10-4FBE-AFFA-53477D3FC8D5}.Release|x86.Build.0 = Release|x86 + {7E33BCB7-19C5-4061-981D-BA695322708A}.Debug|Any CPU.ActiveCfg = Debug|Win32 {7E33BCB7-19C5-4061-981D-BA695322708A}.Debug|x64.ActiveCfg = Debug|x64 {7E33BCB7-19C5-4061-981D-BA695322708A}.Debug|x64.Build.0 = Debug|x64 {7E33BCB7-19C5-4061-981D-BA695322708A}.Debug|x86.ActiveCfg = Debug|Win32 {7E33BCB7-19C5-4061-981D-BA695322708A}.Debug|x86.Build.0 = Debug|Win32 + {7E33BCB7-19C5-4061-981D-BA695322708A}.Release|Any CPU.ActiveCfg = Release|Win32 {7E33BCB7-19C5-4061-981D-BA695322708A}.Release|x64.ActiveCfg = Release|x64 {7E33BCB7-19C5-4061-981D-BA695322708A}.Release|x64.Build.0 = Release|x64 {7E33BCB7-19C5-4061-981D-BA695322708A}.Release|x86.ActiveCfg = Release|Win32 {7E33BCB7-19C5-4061-981D-BA695322708A}.Release|x86.Build.0 = Release|Win32 + {B511B7C9-C8E2-47ED-A0D1-538C00747D30}.Debug|Any CPU.ActiveCfg = Debug|Win32 {B511B7C9-C8E2-47ED-A0D1-538C00747D30}.Debug|x64.ActiveCfg = Debug|x64 {B511B7C9-C8E2-47ED-A0D1-538C00747D30}.Debug|x64.Build.0 = Debug|x64 {B511B7C9-C8E2-47ED-A0D1-538C00747D30}.Debug|x86.ActiveCfg = Debug|Win32 {B511B7C9-C8E2-47ED-A0D1-538C00747D30}.Debug|x86.Build.0 = Debug|Win32 + {B511B7C9-C8E2-47ED-A0D1-538C00747D30}.Release|Any CPU.ActiveCfg = Release|Win32 {B511B7C9-C8E2-47ED-A0D1-538C00747D30}.Release|x64.ActiveCfg = Release|x64 {B511B7C9-C8E2-47ED-A0D1-538C00747D30}.Release|x64.Build.0 = Release|x64 {B511B7C9-C8E2-47ED-A0D1-538C00747D30}.Release|x86.ActiveCfg = Release|Win32 {B511B7C9-C8E2-47ED-A0D1-538C00747D30}.Release|x86.Build.0 = Release|Win32 + {0BB8F82D-874E-45AA-BCA3-20CE0562164A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0BB8F82D-874E-45AA-BCA3-20CE0562164A}.Debug|Any CPU.Build.0 = Debug|Any CPU {0BB8F82D-874E-45AA-BCA3-20CE0562164A}.Debug|x64.ActiveCfg = Debug|Any CPU {0BB8F82D-874E-45AA-BCA3-20CE0562164A}.Debug|x64.Build.0 = Debug|Any CPU {0BB8F82D-874E-45AA-BCA3-20CE0562164A}.Debug|x86.ActiveCfg = Debug|Any CPU {0BB8F82D-874E-45AA-BCA3-20CE0562164A}.Debug|x86.Build.0 = Debug|Any CPU + {0BB8F82D-874E-45AA-BCA3-20CE0562164A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0BB8F82D-874E-45AA-BCA3-20CE0562164A}.Release|Any CPU.Build.0 = Release|Any CPU {0BB8F82D-874E-45AA-BCA3-20CE0562164A}.Release|x64.ActiveCfg = Release|Any CPU {0BB8F82D-874E-45AA-BCA3-20CE0562164A}.Release|x64.Build.0 = Release|Any CPU {0BB8F82D-874E-45AA-BCA3-20CE0562164A}.Release|x86.ActiveCfg = Release|Any CPU {0BB8F82D-874E-45AA-BCA3-20CE0562164A}.Release|x86.Build.0 = Release|Any CPU + {EF3326B5-716F-41D2-AB30-4EFAB30955E2}.Debug|Any CPU.ActiveCfg = Debug|x86 {EF3326B5-716F-41D2-AB30-4EFAB30955E2}.Debug|x64.ActiveCfg = Debug|x64 {EF3326B5-716F-41D2-AB30-4EFAB30955E2}.Debug|x64.Build.0 = Debug|x64 {EF3326B5-716F-41D2-AB30-4EFAB30955E2}.Debug|x86.ActiveCfg = Debug|x86 {EF3326B5-716F-41D2-AB30-4EFAB30955E2}.Debug|x86.Build.0 = Debug|x86 + {EF3326B5-716F-41D2-AB30-4EFAB30955E2}.Release|Any CPU.ActiveCfg = Release|x86 {EF3326B5-716F-41D2-AB30-4EFAB30955E2}.Release|x64.ActiveCfg = Release|x64 {EF3326B5-716F-41D2-AB30-4EFAB30955E2}.Release|x64.Build.0 = Release|x64 {EF3326B5-716F-41D2-AB30-4EFAB30955E2}.Release|x86.ActiveCfg = Release|x86 {EF3326B5-716F-41D2-AB30-4EFAB30955E2}.Release|x86.Build.0 = Release|x86 + {E0C26D3A-504A-4826-BAE2-DE775F865B2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E0C26D3A-504A-4826-BAE2-DE775F865B2A}.Debug|Any CPU.Build.0 = Debug|Any CPU {E0C26D3A-504A-4826-BAE2-DE775F865B2A}.Debug|x64.ActiveCfg = Debug|Any CPU {E0C26D3A-504A-4826-BAE2-DE775F865B2A}.Debug|x64.Build.0 = Debug|Any CPU {E0C26D3A-504A-4826-BAE2-DE775F865B2A}.Debug|x86.ActiveCfg = Debug|Any CPU {E0C26D3A-504A-4826-BAE2-DE775F865B2A}.Debug|x86.Build.0 = Debug|Any CPU + {E0C26D3A-504A-4826-BAE2-DE775F865B2A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E0C26D3A-504A-4826-BAE2-DE775F865B2A}.Release|Any CPU.Build.0 = Release|Any CPU {E0C26D3A-504A-4826-BAE2-DE775F865B2A}.Release|x64.ActiveCfg = Release|Any CPU {E0C26D3A-504A-4826-BAE2-DE775F865B2A}.Release|x64.Build.0 = Release|Any CPU {E0C26D3A-504A-4826-BAE2-DE775F865B2A}.Release|x86.ActiveCfg = Release|Any CPU {E0C26D3A-504A-4826-BAE2-DE775F865B2A}.Release|x86.Build.0 = Release|Any CPU + {41E2A272-150F-42F5-AD40-047AAD9088A0}.Debug|Any CPU.ActiveCfg = Debug|x86 {41E2A272-150F-42F5-AD40-047AAD9088A0}.Debug|x64.ActiveCfg = Debug|x64 {41E2A272-150F-42F5-AD40-047AAD9088A0}.Debug|x64.Build.0 = Debug|x64 {41E2A272-150F-42F5-AD40-047AAD9088A0}.Debug|x86.ActiveCfg = Debug|x86 {41E2A272-150F-42F5-AD40-047AAD9088A0}.Debug|x86.Build.0 = Debug|x86 + {41E2A272-150F-42F5-AD40-047AAD9088A0}.Release|Any CPU.ActiveCfg = Release|x86 {41E2A272-150F-42F5-AD40-047AAD9088A0}.Release|x64.ActiveCfg = Release|x64 {41E2A272-150F-42F5-AD40-047AAD9088A0}.Release|x64.Build.0 = Release|x64 {41E2A272-150F-42F5-AD40-047AAD9088A0}.Release|x86.ActiveCfg = Release|x86 {41E2A272-150F-42F5-AD40-047AAD9088A0}.Release|x86.Build.0 = Release|x86 + {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Debug|Any CPU.ActiveCfg = Debug|Win32 {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Debug|x64.ActiveCfg = Debug|x64 {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Debug|x64.Build.0 = Debug|x64 {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Debug|x86.ActiveCfg = Debug|Win32 {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Debug|x86.Build.0 = Debug|Win32 + {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Release|Any CPU.ActiveCfg = Release|Win32 {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Release|x64.ActiveCfg = Release|x64 {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Release|x64.Build.0 = Release|x64 {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Release|x86.ActiveCfg = Release|Win32 {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Release|x86.Build.0 = Release|Win32 + {13333A6F-6A4A-48CD-865C-0F65135EB018}.Debug|Any CPU.ActiveCfg = Debug|Win32 {13333A6F-6A4A-48CD-865C-0F65135EB018}.Debug|x64.ActiveCfg = Debug|x64 {13333A6F-6A4A-48CD-865C-0F65135EB018}.Debug|x64.Build.0 = Debug|x64 {13333A6F-6A4A-48CD-865C-0F65135EB018}.Debug|x86.ActiveCfg = Debug|Win32 {13333A6F-6A4A-48CD-865C-0F65135EB018}.Debug|x86.Build.0 = Debug|Win32 + {13333A6F-6A4A-48CD-865C-0F65135EB018}.Release|Any CPU.ActiveCfg = Release|Win32 {13333A6F-6A4A-48CD-865C-0F65135EB018}.Release|x64.ActiveCfg = Release|x64 {13333A6F-6A4A-48CD-865C-0F65135EB018}.Release|x64.Build.0 = Release|x64 {13333A6F-6A4A-48CD-865C-0F65135EB018}.Release|x86.ActiveCfg = Release|Win32 {13333A6F-6A4A-48CD-865C-0F65135EB018}.Release|x86.Build.0 = Release|Win32 + {0080F6D1-AEC3-4F89-ADE1-3D22A7EBF99E}.Debug|Any CPU.ActiveCfg = Debug|Win32 {0080F6D1-AEC3-4F89-ADE1-3D22A7EBF99E}.Debug|x64.ActiveCfg = Debug|x64 {0080F6D1-AEC3-4F89-ADE1-3D22A7EBF99E}.Debug|x64.Build.0 = Debug|x64 {0080F6D1-AEC3-4F89-ADE1-3D22A7EBF99E}.Debug|x86.ActiveCfg = Debug|Win32 {0080F6D1-AEC3-4F89-ADE1-3D22A7EBF99E}.Debug|x86.Build.0 = Debug|Win32 + {0080F6D1-AEC3-4F89-ADE1-3D22A7EBF99E}.Release|Any CPU.ActiveCfg = Release|Win32 {0080F6D1-AEC3-4F89-ADE1-3D22A7EBF99E}.Release|x64.ActiveCfg = Release|x64 {0080F6D1-AEC3-4F89-ADE1-3D22A7EBF99E}.Release|x64.Build.0 = Release|x64 {0080F6D1-AEC3-4F89-ADE1-3D22A7EBF99E}.Release|x86.ActiveCfg = Release|Win32 {0080F6D1-AEC3-4F89-ADE1-3D22A7EBF99E}.Release|x86.Build.0 = Release|Win32 + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Debug|Any CPU.Build.0 = Debug|Any CPU {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Debug|x64.ActiveCfg = Debug|Any CPU {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Debug|x64.Build.0 = Debug|Any CPU {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Debug|x86.ActiveCfg = Debug|Any CPU {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Debug|x86.Build.0 = Debug|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Release|Any CPU.Build.0 = Release|Any CPU {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Release|x64.ActiveCfg = Release|Any CPU {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Release|x64.Build.0 = Release|Any CPU {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Release|x86.ActiveCfg = Release|Any CPU {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Release|x86.Build.0 = Release|Any CPU + {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9}.Debug|Any CPU.ActiveCfg = Debug|x86 {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9}.Debug|x64.ActiveCfg = Debug|x64 {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9}.Debug|x64.Build.0 = Debug|x64 {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9}.Debug|x64.Deploy.0 = Debug|x64 {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9}.Debug|x86.ActiveCfg = Debug|x86 {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9}.Debug|x86.Build.0 = Debug|x86 {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9}.Debug|x86.Deploy.0 = Debug|x86 + {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9}.Release|Any CPU.ActiveCfg = Release|x86 {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9}.Release|x64.ActiveCfg = Release|x64 {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9}.Release|x64.Build.0 = Release|x64 {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9}.Release|x64.Deploy.0 = Release|x64 {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9}.Release|x86.ActiveCfg = Release|x86 {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9}.Release|x86.Build.0 = Release|x86 {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9}.Release|x86.Deploy.0 = Release|x86 + {493C7729-2F21-4198-AB09-BDF56BF501D3}.Debug|Any CPU.ActiveCfg = Debug|Win32 {493C7729-2F21-4198-AB09-BDF56BF501D3}.Debug|x64.ActiveCfg = Debug|x64 {493C7729-2F21-4198-AB09-BDF56BF501D3}.Debug|x64.Build.0 = Debug|x64 {493C7729-2F21-4198-AB09-BDF56BF501D3}.Debug|x86.ActiveCfg = Debug|Win32 {493C7729-2F21-4198-AB09-BDF56BF501D3}.Debug|x86.Build.0 = Debug|Win32 + {493C7729-2F21-4198-AB09-BDF56BF501D3}.Release|Any CPU.ActiveCfg = Release|Win32 {493C7729-2F21-4198-AB09-BDF56BF501D3}.Release|x64.ActiveCfg = Release|x64 {493C7729-2F21-4198-AB09-BDF56BF501D3}.Release|x64.Build.0 = Release|x64 {493C7729-2F21-4198-AB09-BDF56BF501D3}.Release|x86.ActiveCfg = Release|Win32 {493C7729-2F21-4198-AB09-BDF56BF501D3}.Release|x86.Build.0 = Release|Win32 + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|x64.ActiveCfg = Debug|x64 + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|x64.Build.0 = Debug|x64 + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|x86.ActiveCfg = Debug|x86 + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|x86.Build.0 = Debug|x86 + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Release|Any CPU.Build.0 = Release|Any CPU + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Release|x64.ActiveCfg = Release|Any CPU + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Release|x64.Build.0 = Release|Any CPU + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Release|x86.ActiveCfg = Release|Any CPU + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -326,6 +400,7 @@ Global {FC05C557-C974-4CB3-9DA7-BB5476710E91} = {CFB651EC-DAA4-4A11-ABCD-C77F90602EB5} {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9} = {CFB651EC-DAA4-4A11-ABCD-C77F90602EB5} {493C7729-2F21-4198-AB09-BDF56BF501D3} = {CFB651EC-DAA4-4A11-ABCD-C77F90602EB5} + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9} = {539DBDEF-3B49-4503-9BD3-7EB83C2179CB} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5AE8C9D7-2613-4E1A-A4F2-579BAC28D0A2} From 2f97489280772987c2210818faf4dd87582ac36d Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Tue, 18 May 2021 15:19:05 -0700 Subject: [PATCH 02/24] add guid patch to nuspec and build cmd --- nuget/Microsoft.Windows.CsWinRT.nuspec | 1 + src/build.cmd | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/nuget/Microsoft.Windows.CsWinRT.nuspec b/nuget/Microsoft.Windows.CsWinRT.nuspec index 6c7ac3a44..bf4629492 100644 --- a/nuget/Microsoft.Windows.CsWinRT.nuspec +++ b/nuget/Microsoft.Windows.CsWinRT.nuspec @@ -34,5 +34,6 @@ + diff --git a/src/build.cmd b/src/build.cmd index ef1072617..d738a1a6b 100644 --- a/src/build.cmd +++ b/src/build.cmd @@ -184,8 +184,9 @@ set net5_runtime=%this_dir%WinRT.Runtime\bin\%cswinrt_configuration%\net5.0\WinR set source_generator=%this_dir%Authoring\WinRT.SourceGenerator\bin\%cswinrt_configuration%\netstandard2.0\WinRT.SourceGenerator.dll set winrt_host_%cswinrt_platform%=%this_dir%_build\%cswinrt_platform%\%cswinrt_configuration%\WinRT.Host\bin\WinRT.Host.dll set winrt_shim=%this_dir%Authoring\WinRT.Host.Shim\bin\%cswinrt_configuration%\net5.0\WinRT.Host.Shim.dll +set guid_patch=%this_dir%Perf\GuidPatch\bin\%cswinrt_configuration%\net5.0\GuidPatch.exe echo Creating nuget package -call :exec %nuget_dir%\nuget pack %this_dir%..\nuget\Microsoft.Windows.CsWinRT.nuspec -Properties cswinrt_exe=%cswinrt_exe%;netstandard2_runtime=%netstandard2_runtime%;net5_runtime=%net5_runtime%;source_generator=%source_generator%;cswinrt_nuget_version=%cswinrt_version_string%;winrt_host_x86=%winrt_host_x86%;winrt_host_x64=%winrt_host_x64%;winrt_host_arm=%winrt_host_arm%;winrt_host_arm64=%winrt_host_arm64%;winrt_shim=%winrt_shim% -OutputDirectory %cswinrt_bin_dir% -NonInteractive -Verbosity Detailed -NoPackageAnalysis +call :exec %nuget_dir%\nuget pack %this_dir%..\nuget\Microsoft.Windows.CsWinRT.nuspec -Properties cswinrt_exe=%cswinrt_exe%;netstandard2_runtime=%netstandard2_runtime%;net5_runtime=%net5_runtime%;source_generator=%source_generator%;cswinrt_nuget_version=%cswinrt_version_string%;winrt_host_x86=%winrt_host_x86%;winrt_host_x64=%winrt_host_x64%;winrt_host_arm=%winrt_host_arm%;winrt_host_arm64=%winrt_host_arm64%;winrt_shim=%winrt_shim%;guid_patch=%guid_patch% -OutputDirectory %cswinrt_bin_dir% -NonInteractive -Verbosity Detailed -NoPackageAnalysis goto :eof :exec From bfcc5ddcbbb7f84094ea7dd61b2074950b4f63bc Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Thu, 20 May 2021 15:39:28 -0700 Subject: [PATCH 03/24] Update WinUI3 pkg reference in Tests --- .../AuthoringConsumptionTest.vcxproj | 8 ++++---- src/Tests/AuthoringConsumptionTest/packages.config | 2 +- .../AuthoringWinUITest/AuthoringWinUITest/App.xaml.cpp | 7 ++++++- .../AuthoringWinUITest/AuthoringWinUITest.vcxproj | 8 ++++---- .../AuthoringWinUITest/AuthoringWinUITest/packages.config | 2 +- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/Tests/AuthoringConsumptionTest/AuthoringConsumptionTest.vcxproj b/src/Tests/AuthoringConsumptionTest/AuthoringConsumptionTest.vcxproj index 2c2149c4f..0001410ad 100644 --- a/src/Tests/AuthoringConsumptionTest/AuthoringConsumptionTest.vcxproj +++ b/src/Tests/AuthoringConsumptionTest/AuthoringConsumptionTest.vcxproj @@ -1,6 +1,6 @@ - + @@ -88,8 +88,8 @@ - + @@ -160,8 +160,8 @@ - - + + \ No newline at end of file diff --git a/src/Tests/AuthoringConsumptionTest/packages.config b/src/Tests/AuthoringConsumptionTest/packages.config index 305839ee8..20000ce0d 100644 --- a/src/Tests/AuthoringConsumptionTest/packages.config +++ b/src/Tests/AuthoringConsumptionTest/packages.config @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/App.xaml.cpp b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/App.xaml.cpp index 50d0f5ca7..774faa498 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/App.xaml.cpp +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/App.xaml.cpp @@ -8,6 +8,11 @@ using namespace Windows::Foundation; using namespace Microsoft::UI::Xaml; using namespace Microsoft::UI::Xaml::Controls; using namespace Microsoft::UI::Xaml::Navigation; +using namespace Microsoft::UI::Xaml::Controls::Primitives; +using namespace Microsoft::UI::Xaml::Data; +using namespace Microsoft::UI::Xaml::Input; +using namespace Microsoft::UI::Xaml::Interop; +using namespace Microsoft::UI::Xaml::Media; using namespace AuthoringWinUITest; using namespace AuthoringWinUITest::implementation; @@ -21,7 +26,7 @@ using namespace AuthoringWinUITest::implementation; App::App() { InitializeComponent(); - Suspending({ this, &App::OnSuspending }); + // Suspending({ this, &App::OnSuspending }); #if defined _DEBUG && !defined DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION UnhandledException([this](IInspectable const&, UnhandledExceptionEventArgs const& e) diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj index 4c158c7dc..d1641a4a6 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj @@ -1,6 +1,6 @@  - + true @@ -170,7 +170,7 @@ - + @@ -179,7 +179,7 @@ - - + + \ No newline at end of file diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/packages.config b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/packages.config index 7d3974eb9..1350f41f7 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/packages.config +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/packages.config @@ -2,5 +2,5 @@ - + \ No newline at end of file From 52f5c99aae9287eb7812601bdd250eb8e3d8fb1c Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Thu, 20 May 2021 19:16:18 -0700 Subject: [PATCH 04/24] Feedback --- nuget/Microsoft.Windows.CsWinRT.targets | 30 ++++++++++++++-- src/Directory.Build.props | 5 +++ src/Perf/GuidPatch/GuidPatch.csproj | 2 +- src/Perf/GuidPatch/GuidPatcher.cs | 4 +-- src/Perf/GuidPatch/Program.cs | 46 +++++++++++++++++-------- src/build.cmd | 3 +- src/cswinrt.sln | 5 +-- src/cswinrt/main.cpp | 1 + 8 files changed, 71 insertions(+), 25 deletions(-) diff --git a/nuget/Microsoft.Windows.CsWinRT.targets b/nuget/Microsoft.Windows.CsWinRT.targets index 2ce814b4d..e9a29d767 100644 --- a/nuget/Microsoft.Windows.CsWinRT.targets +++ b/nuget/Microsoft.Windows.CsWinRT.targets @@ -149,8 +149,34 @@ $(CsWinRTFilters) - - + + + + $(CsWinRTGuidPatchPath) + $(CsWinRTGuidPatchRuntimePath) + + $(CsWinRTPath)build\tools\ + $(CsWinRTPath)lib\net5.0\ + + @(BuiltProjectOutputGroupKeyOutput->'%(Identity)') + + + + + + + + + + + + + + + diff --git a/src/Directory.Build.props b/src/Directory.Build.props index eee4c5c30..a0ee6a9e3 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -26,6 +26,11 @@ $(DefineConstants);MANUAL_IUNKNOWN + + $(MSBuildProjectDirectory)\Perf\GuidPatch\bin\$(Platform)\$(Configuration)\net5.0\ + $(MSBuildProjectDirectory)\WinRT.Runtime\bin\$(Configuration)\net5.0\ + + 0.0.0.0 0.0.0-private.0 diff --git a/src/Perf/GuidPatch/GuidPatch.csproj b/src/Perf/GuidPatch/GuidPatch.csproj index c9ca52748..3d9a8f99a 100644 --- a/src/Perf/GuidPatch/GuidPatch.csproj +++ b/src/Perf/GuidPatch/GuidPatch.csproj @@ -4,7 +4,7 @@ Exe net5.0 enable - AnyCPU;x64;x86 + AnyCPU diff --git a/src/Perf/GuidPatch/GuidPatcher.cs b/src/Perf/GuidPatch/GuidPatcher.cs index 2af033fb1..00e7e82cb 100644 --- a/src/Perf/GuidPatch/GuidPatcher.cs +++ b/src/Perf/GuidPatch/GuidPatcher.cs @@ -30,7 +30,7 @@ class GuidPatcher private readonly TypeDefinition guidDataBlockType; private SignatureGenerator signatureGenerator; - public GuidPatcher(string assemblyPath, IAssemblyResolver assemblyResolver) + public GuidPatcher(string assemblyPath, IAssemblyResolver assemblyResolver, AssemblyDefinition winRTRuntime) { assembly = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters(ReadingMode.Deferred) { @@ -42,7 +42,7 @@ public GuidPatcher(string assemblyPath, IAssemblyResolver assemblyResolver) ApplyWindowsRuntimeProjections = false }); - winRTRuntimeAssembly = assemblyResolver.Resolve(new AssemblyNameReference("WinRT.Runtime", default)); + winRTRuntimeAssembly = winRTRuntime; // assemblyResolver.Resolve(new AssemblyNameReference("WinRT.Runtime", default)); guidImplementationDetailsType = new TypeDefinition(null, "", TypeAttributes.AutoClass | TypeAttributes.Sealed, assembly.MainModule.TypeSystem.Object); diff --git a/src/Perf/GuidPatch/Program.cs b/src/Perf/GuidPatch/Program.cs index 0f993eb01..579788732 100644 --- a/src/Perf/GuidPatch/Program.cs +++ b/src/Perf/GuidPatch/Program.cs @@ -1,4 +1,6 @@ -using System; +using Mono.Cecil; +using System; +using System.IO; namespace GuidPatch { @@ -6,21 +8,35 @@ class Program { static void Main(string[] args) { - Console.WriteLine("Hello World!"); + if (args.Length != 2) + { + Console.WriteLine($"Expected to be given two arguments. Given {args.Length}"); + } + else + { + /* The first argument given is the .dll to patch + The second argument is the folder to look for winrt.runtime in */ + var resolver = new DefaultAssemblyResolver(); - /* - var resolver = new DefaultAssemblyResolver(); - resolver.AddSearchDirectory("TestData"); - resolver.AddSearchDirectory("C:/Program Files/dotnet/packs/Microsoft.NETCore.App.Ref/5.0.0/ref/net5.0"); - var guidPatcher = new GuidPatcher( - "TestData/Windows.dll", - resolver); - int numPatches = guidPatcher.ProcessAssembly(); - Directory.CreateDirectory("Output"); - guidPatcher.SaveAssembly("Output"); - - Console.WriteLine($"{numPatches} IID calculations/fetches patched"); - */ + try + { + resolver.AddSearchDirectory(args[1]); + AssemblyDefinition winRTRuntimeAssembly = resolver.Resolve(new AssemblyNameReference("WinRT.Runtime", default)); + var guidPatcher = new GuidPatcher( + args[0], + resolver, + winRTRuntimeAssembly); + int numPatches = guidPatcher.ProcessAssembly(); + Directory.CreateDirectory("GuidPatcherOutput"); + guidPatcher.SaveAssembly("GuidPatcherOutput"); + Console.WriteLine($"{numPatches} IID calculations/fetches patched"); + } + catch (AssemblyResolutionException) + { + Console.WriteLine("Failed to resolve WinRT.Runtime, shutting down."); + return; + } + } } } } diff --git a/src/build.cmd b/src/build.cmd index d738a1a6b..2ca794b53 100644 --- a/src/build.cmd +++ b/src/build.cmd @@ -131,6 +131,7 @@ if ErrorLevel 1 ( exit /b !ErrorLevel! ) if "%cswinrt_build_only%"=="true" goto :eof +if "%cswinrt_buildpack%"=="true" goto :package :test :unittest @@ -184,7 +185,7 @@ set net5_runtime=%this_dir%WinRT.Runtime\bin\%cswinrt_configuration%\net5.0\WinR set source_generator=%this_dir%Authoring\WinRT.SourceGenerator\bin\%cswinrt_configuration%\netstandard2.0\WinRT.SourceGenerator.dll set winrt_host_%cswinrt_platform%=%this_dir%_build\%cswinrt_platform%\%cswinrt_configuration%\WinRT.Host\bin\WinRT.Host.dll set winrt_shim=%this_dir%Authoring\WinRT.Host.Shim\bin\%cswinrt_configuration%\net5.0\WinRT.Host.Shim.dll -set guid_patch=%this_dir%Perf\GuidPatch\bin\%cswinrt_configuration%\net5.0\GuidPatch.exe +set guid_patch=%this_dir%Perf\GuidPatch\bin\%cswinrt_platform%\%cswinrt_configuration%\net5.0\GuidPatch.exe echo Creating nuget package call :exec %nuget_dir%\nuget pack %this_dir%..\nuget\Microsoft.Windows.CsWinRT.nuspec -Properties cswinrt_exe=%cswinrt_exe%;netstandard2_runtime=%netstandard2_runtime%;net5_runtime=%net5_runtime%;source_generator=%source_generator%;cswinrt_nuget_version=%cswinrt_version_string%;winrt_host_x86=%winrt_host_x86%;winrt_host_x64=%winrt_host_x64%;winrt_host_arm=%winrt_host_arm%;winrt_host_arm64=%winrt_host_arm64%;winrt_shim=%winrt_shim%;guid_patch=%guid_patch% -OutputDirectory %cswinrt_bin_dir% -NonInteractive -Verbosity Detailed -NoPackageAnalysis goto :eof diff --git a/src/cswinrt.sln b/src/cswinrt.sln index b28214168..0f0219794 100644 --- a/src/cswinrt.sln +++ b/src/cswinrt.sln @@ -101,7 +101,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AuthoringWinUITest", "Tests EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Perf", "Perf", "{539DBDEF-3B49-4503-9BD3-7EB83C2179CB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GuidPatch", "Perf\GuidPatch\GuidPatch.csproj", "{AE3B0611-2FBB-42AB-A245-B4E79868A5F9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GuidPatch", "Perf\GuidPatch\GuidPatch.csproj", "{AE3B0611-2FBB-42AB-A245-B4E79868A5F9}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -299,7 +299,6 @@ Global {41E2A272-150F-42F5-AD40-047AAD9088A0}.Release|x86.Build.0 = Release|x86 {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Debug|Any CPU.ActiveCfg = Debug|Win32 {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Debug|x64.ActiveCfg = Debug|x64 - {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Debug|x64.Build.0 = Debug|x64 {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Debug|x86.ActiveCfg = Debug|Win32 {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Debug|x86.Build.0 = Debug|Win32 {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Release|Any CPU.ActiveCfg = Release|Win32 @@ -341,7 +340,6 @@ Global {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Release|x86.Build.0 = Release|Any CPU {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9}.Debug|Any CPU.ActiveCfg = Debug|x86 {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9}.Debug|x64.ActiveCfg = Debug|x64 - {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9}.Debug|x64.Build.0 = Debug|x64 {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9}.Debug|x64.Deploy.0 = Debug|x64 {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9}.Debug|x86.ActiveCfg = Debug|x86 {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9}.Debug|x86.Build.0 = Debug|x86 @@ -355,7 +353,6 @@ Global {75B1621F-EC51-4D77-BD7E-BEE576B3ADC9}.Release|x86.Deploy.0 = Release|x86 {493C7729-2F21-4198-AB09-BDF56BF501D3}.Debug|Any CPU.ActiveCfg = Debug|Win32 {493C7729-2F21-4198-AB09-BDF56BF501D3}.Debug|x64.ActiveCfg = Debug|x64 - {493C7729-2F21-4198-AB09-BDF56BF501D3}.Debug|x64.Build.0 = Debug|x64 {493C7729-2F21-4198-AB09-BDF56BF501D3}.Debug|x86.ActiveCfg = Debug|Win32 {493C7729-2F21-4198-AB09-BDF56BF501D3}.Debug|x86.Build.0 = Debug|Win32 {493C7729-2F21-4198-AB09-BDF56BF501D3}.Release|Any CPU.ActiveCfg = Release|Win32 diff --git a/src/cswinrt/main.cpp b/src/cswinrt/main.cpp index 75b31dfd2..4a1fff5cb 100644 --- a/src/cswinrt/main.cpp +++ b/src/cswinrt/main.cpp @@ -119,6 +119,7 @@ Where is one or more of: int result{}; writer w; + /* Special case the usage exceptions to print CLI options */ try { auto start = get_start_time(); From d4baf0b241b52ab83ab997d393a77f40de4677d8 Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Mon, 24 May 2021 14:03:48 -0700 Subject: [PATCH 05/24] More feedback. --- nuget/Microsoft.Windows.CsWinRT.nuspec | 2 +- nuget/Microsoft.Windows.CsWinRT.targets | 34 ++-- src/Directory.Build.props | 4 +- .../CecilExtensions.cs | 0 .../FolderAssemblyResolver.cs | 0 .../GuidPatcher.cs | 0 .../IIDOptimizer.csproj} | 0 .../{GuidPatch => IIDOptimizer}/Program.cs | 4 +- .../SignatureEmitter.cs | 0 .../SignatureGenerator.cs | 0 .../AuthoringConsumptionTest.vcxproj | 18 +- .../AuthoringConsumptionTest/packages.config | 5 +- src/Tests/AuthoringTest/AuthoringTest.csproj | 1 + .../AuthoringWinUITest/App.xaml.cpp | 2 +- .../AuthoringWinUITest.vcxproj | 18 +- .../AuthoringWinUITest.vcxproj.filters | 1 - .../AuthoringWinUITest/packages.config | 5 +- .../DiagnosticTests/DiagnosticTests.csproj | 1 + src/Tests/UnitTest/UnitTest.csproj | 1 + src/build.cmd | 2 +- src/cswinrt.sln | 2 +- src/quickbuild.cmd | 191 ++++++++++++++++++ 22 files changed, 255 insertions(+), 36 deletions(-) rename src/Perf/{GuidPatch => IIDOptimizer}/CecilExtensions.cs (100%) rename src/Perf/{GuidPatch => IIDOptimizer}/FolderAssemblyResolver.cs (100%) rename src/Perf/{GuidPatch => IIDOptimizer}/GuidPatcher.cs (100%) rename src/Perf/{GuidPatch/GuidPatch.csproj => IIDOptimizer/IIDOptimizer.csproj} (100%) rename src/Perf/{GuidPatch => IIDOptimizer}/Program.cs (88%) rename src/Perf/{GuidPatch => IIDOptimizer}/SignatureEmitter.cs (100%) rename src/Perf/{GuidPatch => IIDOptimizer}/SignatureGenerator.cs (100%) create mode 100644 src/quickbuild.cmd diff --git a/nuget/Microsoft.Windows.CsWinRT.nuspec b/nuget/Microsoft.Windows.CsWinRT.nuspec index bf4629492..a6308d9f3 100644 --- a/nuget/Microsoft.Windows.CsWinRT.nuspec +++ b/nuget/Microsoft.Windows.CsWinRT.nuspec @@ -34,6 +34,6 @@ - + diff --git a/nuget/Microsoft.Windows.CsWinRT.targets b/nuget/Microsoft.Windows.CsWinRT.targets index e9a29d767..1aab5764b 100644 --- a/nuget/Microsoft.Windows.CsWinRT.targets +++ b/nuget/Microsoft.Windows.CsWinRT.targets @@ -148,35 +148,35 @@ $(CsWinRTFilters) - + - + + + + + - $(CsWinRTGuidPatchPath) - $(CsWinRTGuidPatchRuntimePath) + $(CsWinRTIIDOptimizerPath) + $(CsWinRTIIDOptimizerRuntimePath) - $(CsWinRTPath)build\tools\ - $(CsWinRTPath)lib\net5.0\ + $(CsWinRTPath)build\tools\GuidPatch\ + $(CsWinRTPath)lib\net5.0\ - @(BuiltProjectOutputGroupKeyOutput->'%(Identity)') + + @(BuiltProjectOutputGroupKeyOutput->'%(Identity)') - - + - - + - - - + + diff --git a/src/Directory.Build.props b/src/Directory.Build.props index a0ee6a9e3..6043c4aee 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -27,8 +27,8 @@ - $(MSBuildProjectDirectory)\Perf\GuidPatch\bin\$(Platform)\$(Configuration)\net5.0\ - $(MSBuildProjectDirectory)\WinRT.Runtime\bin\$(Configuration)\net5.0\ + $(MSBuildThisFileDirectory)Perf\IIDOptimizer\bin\$(Configuration)\net5.0\ + $(MSBuildThisFileDirectory)WinRT.Runtime\bin\$(Configuration)\net5.0\ diff --git a/src/Perf/GuidPatch/CecilExtensions.cs b/src/Perf/IIDOptimizer/CecilExtensions.cs similarity index 100% rename from src/Perf/GuidPatch/CecilExtensions.cs rename to src/Perf/IIDOptimizer/CecilExtensions.cs diff --git a/src/Perf/GuidPatch/FolderAssemblyResolver.cs b/src/Perf/IIDOptimizer/FolderAssemblyResolver.cs similarity index 100% rename from src/Perf/GuidPatch/FolderAssemblyResolver.cs rename to src/Perf/IIDOptimizer/FolderAssemblyResolver.cs diff --git a/src/Perf/GuidPatch/GuidPatcher.cs b/src/Perf/IIDOptimizer/GuidPatcher.cs similarity index 100% rename from src/Perf/GuidPatch/GuidPatcher.cs rename to src/Perf/IIDOptimizer/GuidPatcher.cs diff --git a/src/Perf/GuidPatch/GuidPatch.csproj b/src/Perf/IIDOptimizer/IIDOptimizer.csproj similarity index 100% rename from src/Perf/GuidPatch/GuidPatch.csproj rename to src/Perf/IIDOptimizer/IIDOptimizer.csproj diff --git a/src/Perf/GuidPatch/Program.cs b/src/Perf/IIDOptimizer/Program.cs similarity index 88% rename from src/Perf/GuidPatch/Program.cs rename to src/Perf/IIDOptimizer/Program.cs index 579788732..0e1eb9b9e 100644 --- a/src/Perf/GuidPatch/Program.cs +++ b/src/Perf/IIDOptimizer/Program.cs @@ -27,8 +27,8 @@ static void Main(string[] args) resolver, winRTRuntimeAssembly); int numPatches = guidPatcher.ProcessAssembly(); - Directory.CreateDirectory("GuidPatcherOutput"); - guidPatcher.SaveAssembly("GuidPatcherOutput"); + Directory.CreateDirectory("obj\\IIDOptimizer"); + guidPatcher.SaveAssembly("obj\\IIDOptimizer"); Console.WriteLine($"{numPatches} IID calculations/fetches patched"); } catch (AssemblyResolutionException) diff --git a/src/Perf/GuidPatch/SignatureEmitter.cs b/src/Perf/IIDOptimizer/SignatureEmitter.cs similarity index 100% rename from src/Perf/GuidPatch/SignatureEmitter.cs rename to src/Perf/IIDOptimizer/SignatureEmitter.cs diff --git a/src/Perf/GuidPatch/SignatureGenerator.cs b/src/Perf/IIDOptimizer/SignatureGenerator.cs similarity index 100% rename from src/Perf/GuidPatch/SignatureGenerator.cs rename to src/Perf/IIDOptimizer/SignatureGenerator.cs diff --git a/src/Tests/AuthoringConsumptionTest/AuthoringConsumptionTest.vcxproj b/src/Tests/AuthoringConsumptionTest/AuthoringConsumptionTest.vcxproj index 0001410ad..944db0d6b 100644 --- a/src/Tests/AuthoringConsumptionTest/AuthoringConsumptionTest.vcxproj +++ b/src/Tests/AuthoringConsumptionTest/AuthoringConsumptionTest.vcxproj @@ -1,6 +1,9 @@ - + + + + @@ -89,7 +92,9 @@ - + + + @@ -161,7 +166,12 @@ - - + + + + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringConsumptionTest/packages.config b/src/Tests/AuthoringConsumptionTest/packages.config index 20000ce0d..e9106f991 100644 --- a/src/Tests/AuthoringConsumptionTest/packages.config +++ b/src/Tests/AuthoringConsumptionTest/packages.config @@ -1,7 +1,10 @@  + + + + - \ No newline at end of file diff --git a/src/Tests/AuthoringTest/AuthoringTest.csproj b/src/Tests/AuthoringTest/AuthoringTest.csproj index fb1fd1db2..5463316af 100644 --- a/src/Tests/AuthoringTest/AuthoringTest.csproj +++ b/src/Tests/AuthoringTest/AuthoringTest.csproj @@ -7,6 +7,7 @@ + true diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/App.xaml.cpp b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/App.xaml.cpp index 774faa498..91cc89511 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/App.xaml.cpp +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/App.xaml.cpp @@ -26,7 +26,7 @@ using namespace AuthoringWinUITest::implementation; App::App() { InitializeComponent(); - // Suspending({ this, &App::OnSuspending }); + Suspending({ this, &App::OnSuspending }); #if defined _DEBUG && !defined DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION UnhandledException([this](IInspectable const&, UnhandledExceptionEventArgs const& e) diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj index d1641a4a6..db6ad9941 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj @@ -1,6 +1,9 @@  - + + + + true @@ -170,7 +173,9 @@ - + + + @@ -179,7 +184,12 @@ - - + + + + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj.filters b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj.filters index fd7f002af..234faee9a 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj.filters +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj.filters @@ -7,7 +7,6 @@ - diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/packages.config b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/packages.config index 1350f41f7..4af55f681 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/packages.config +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/packages.config @@ -1,6 +1,9 @@  + + + + - \ No newline at end of file diff --git a/src/Tests/DiagnosticTests/DiagnosticTests.csproj b/src/Tests/DiagnosticTests/DiagnosticTests.csproj index dd4af04ad..e7af4f914 100644 --- a/src/Tests/DiagnosticTests/DiagnosticTests.csproj +++ b/src/Tests/DiagnosticTests/DiagnosticTests.csproj @@ -3,6 +3,7 @@ net5.0-windows10.0.19041.0 false + true diff --git a/src/Tests/UnitTest/UnitTest.csproj b/src/Tests/UnitTest/UnitTest.csproj index e63aeb190..a00ffb573 100644 --- a/src/Tests/UnitTest/UnitTest.csproj +++ b/src/Tests/UnitTest/UnitTest.csproj @@ -9,6 +9,7 @@ true true false + true diff --git a/src/build.cmd b/src/build.cmd index 2ca794b53..d9ca387da 100644 --- a/src/build.cmd +++ b/src/build.cmd @@ -185,7 +185,7 @@ set net5_runtime=%this_dir%WinRT.Runtime\bin\%cswinrt_configuration%\net5.0\WinR set source_generator=%this_dir%Authoring\WinRT.SourceGenerator\bin\%cswinrt_configuration%\netstandard2.0\WinRT.SourceGenerator.dll set winrt_host_%cswinrt_platform%=%this_dir%_build\%cswinrt_platform%\%cswinrt_configuration%\WinRT.Host\bin\WinRT.Host.dll set winrt_shim=%this_dir%Authoring\WinRT.Host.Shim\bin\%cswinrt_configuration%\net5.0\WinRT.Host.Shim.dll -set guid_patch=%this_dir%Perf\GuidPatch\bin\%cswinrt_platform%\%cswinrt_configuration%\net5.0\GuidPatch.exe +set guid_patch=%this_dir%Perf\IIDOptimizer\bin\%cswinrt_configuration%\net5.0\*.* echo Creating nuget package call :exec %nuget_dir%\nuget pack %this_dir%..\nuget\Microsoft.Windows.CsWinRT.nuspec -Properties cswinrt_exe=%cswinrt_exe%;netstandard2_runtime=%netstandard2_runtime%;net5_runtime=%net5_runtime%;source_generator=%source_generator%;cswinrt_nuget_version=%cswinrt_version_string%;winrt_host_x86=%winrt_host_x86%;winrt_host_x64=%winrt_host_x64%;winrt_host_arm=%winrt_host_arm%;winrt_host_arm64=%winrt_host_arm64%;winrt_shim=%winrt_shim%;guid_patch=%guid_patch% -OutputDirectory %cswinrt_bin_dir% -NonInteractive -Verbosity Detailed -NoPackageAnalysis goto :eof diff --git a/src/cswinrt.sln b/src/cswinrt.sln index 0f0219794..57e0e2f1f 100644 --- a/src/cswinrt.sln +++ b/src/cswinrt.sln @@ -101,7 +101,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AuthoringWinUITest", "Tests EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Perf", "Perf", "{539DBDEF-3B49-4503-9BD3-7EB83C2179CB}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GuidPatch", "Perf\GuidPatch\GuidPatch.csproj", "{AE3B0611-2FBB-42AB-A245-B4E79868A5F9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IIDOptimizer", "Perf\IIDOptimizer\IIDOptimizer.csproj", "{AE3B0611-2FBB-42AB-A245-B4E79868A5F9}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/quickbuild.cmd b/src/quickbuild.cmd new file mode 100644 index 000000000..4bd09048a --- /dev/null +++ b/src/quickbuild.cmd @@ -0,0 +1,191 @@ +@echo off +if /i "%cswinrt_echo%" == "on" @echo on + +set CsWinRTNet5SdkVersion=5.0.100 + +set this_dir=%~dp0 + +:dotnet +rem Install required .NET 5 SDK version and add to environment +set DOTNET_ROOT=%LocalAppData%\Microsoft\dotnet +set DOTNET_ROOT(86)=%LocalAppData%\Microsoft\dotnet\x86 +set path=%DOTNET_ROOT%;%path% + +:globaljson +rem Create global.json for current .NET SDK, and with allowPrerelease=true +set global_json=%this_dir%global.json +echo { > %global_json% +echo "sdk": { >> %global_json% +echo "version": "%CsWinRTNet5SdkVersion%", >> %global_json% +echo "allowPrerelease": true >> %global_json% +echo } >> %global_json% +echo } >> %global_json% + +rem Preserve above for Visual Studio launch inheritance +setlocal ENABLEDELAYEDEXPANSION + +:params +set cswinrt_platform=%1 +set cswinrt_configuration=%2 +set cswinrt_version_number=%3 +set cswinrt_version_string=%4 +set cswinrt_assembly_version=%5 +set "%6"!="" set cswinrt_label=%6 + +if "%cswinrt_platform%"=="" set cswinrt_platform=x64 + +if /I "%cswinrt_platform%" equ "all" ( + if "%cswinrt_configuration%"=="" ( + set cswinrt_configuration=all + ) + call %0 x86 !cswinrt_configuration! !cswinrt_version_number! !cswinrt_version_string! !cswinrt_assembly_version! + call %0 x64 !cswinrt_configuration! !cswinrt_version_number! !cswinrt_version_string! !cswinrt_assembly_version! + call %0 arm !cswinrt_configuration! !cswinrt_version_number! !cswinrt_version_string! !cswinrt_assembly_version! + call %0 arm64 !cswinrt_configuration! !cswinrt_version_number! !cswinrt_version_string! !cswinrt_assembly_version! + goto :eof +) + +if /I "%cswinrt_configuration%" equ "all" ( + call %0 %cswinrt_platform% Debug !cswinrt_version_number! !cswinrt_version_string! !cswinrt_assembly_version! + call %0 %cswinrt_platform% Release !cswinrt_version_number! !cswinrt_version_string! !cswinrt_assembly_version! + goto :eof +) + +if "%cswinrt_configuration%"=="" ( + set cswinrt_configuration=Release +) + +if "%cswinrt_version_number%"=="" set cswinrt_version_number=0.0.0.0 +if "%cswinrt_version_string%"=="" set cswinrt_version_string=0.0.0-private.0 +if "%cswinrt_assembly_version%"=="" set cswinrt_assembly_version=0.0.0.0 + +if "%cswinrt_baseline_breaking_compat_errors%"=="" set cswinrt_baseline_breaking_compat_errors=false +if "%cswinrt_baseline_assembly_version_compat_errors%"=="" set cswinrt_baseline_assembly_version_compat_errors=false + +rem Generate prerelease targets file to exercise build warnings +set prerelease_targets=%this_dir%..\nuget\Microsoft.Windows.CsWinRT.Prerelease.targets +rem Create default %prerelease_targets% +echo ^ > %prerelease_targets% +echo ^> %prerelease_targets% +echo Condition="'$(NetCoreSdkVersion)' ^!= '%CsWinRTNet5SdkVersion%' and '$(Net5SdkVersion)' ^!= '%CsWinRTNet5SdkVersion%'"^> >> %prerelease_targets% +echo ^ >> %prerelease_targets% +echo ^ >> %prerelease_targets% +echo ^ >> %prerelease_targets% + +goto :skip_build_tools +rem VS 16.X BuildTools support (when a prerelease VS is required, until it is deployed to Azure Devops agents) +msbuild -ver | findstr 16.X >nul +if ErrorLevel 1 ( + echo Using VS Build Tools 16.X + if %cswinrt_platform%==x86 ( + set msbuild_path="%this_dir%.buildtools\MSBuild\Current\Bin\\" + ) else ( + set msbuild_path="%this_dir%.buildtools\MSBuild\Current\Bin\amd64\\" + ) + if not exist !msbuild_path! ( + if not exist .buildtools md .buildtools + powershell -NoProfile -ExecutionPolicy unrestricted -File .\get_buildtools.ps1 + ) + set nuget_params=-MSBuildPath !msbuild_path! +) else ( + set msbuild_path= + set nuget_params= +) +:skip_build_tools + +if not "%cswinrt_label%"=="" goto %cswinrt_label% + +:restore +rem When a preview nuget is required, update -self doesn't work, so manually update +set nuget_dir=%this_dir%.nuget +if exist %nuget_dir%\nuget.exe ( + %nuget_dir%\nuget.exe | findstr 5.8.0 >nul + if ErrorLevel 1 ( + echo Updating to nuget 5.8.0 + rd /s/q %nuget_dir% >nul 2>&1 + ) +) +if not exist %nuget_dir% md %nuget_dir% +if not exist %nuget_dir%\nuget.exe powershell -Command "Invoke-WebRequest https://dist.nuget.org/win-x86-commandline/v5.8.0-preview.2/nuget.exe -OutFile %nuget_dir%\nuget.exe" +%nuget_dir%\nuget update -self +rem Note: packages.config-based (vcxproj) projects do not support msbuild /t:restore +call %this_dir%get_testwinrt.cmd +call :exec %nuget_dir%\nuget.exe restore %nuget_params% %this_dir%cswinrt.sln + +:build +echo Building cswinrt for %cswinrt_platform% %cswinrt_configuration% +call :exec %msbuild_path%msbuild.exe %cswinrt_build_params% /p:platform=%cswinrt_platform%;configuration=%cswinrt_configuration%;VersionNumber=%cswinrt_version_number%;VersionString=%cswinrt_version_string%;AssemblyVersionNumber=%cswinrt_assembly_version%;GenerateTestProjection=true;BaselineAllAPICompatError=%cswinrt_baseline_breaking_compat_errors%;BaselineAllMatchingRefApiCompatError=%cswinrt_baseline_assembly_version_compat_errors% %this_dir%cswinrt.sln +if ErrorLevel 1 ( + echo. + echo ERROR: Build failed + exit /b !ErrorLevel! +) +if "%cswinrt_build_only%"=="true" goto :eof +if "%cswinrt_buildpack%"=="true" goto :package + +:test +:unittest +rem Build/Run xUnit tests, generating xml output report for Azure Devops reporting, via XunitXml.TestLogger NuGet +echo Running cswinrt unit tests for %cswinrt_platform% %cswinrt_configuration% +set dotnet_exe="%DOTNET_ROOT%\dotnet.exe" +if not exist %dotnet_exe% ( + if %cswinrt_platform%==x86 ( + set dotnet_exe="%ProgramFiles(x86)%\dotnet\dotnet.exe" + ) else ( + set dotnet_exe="%ProgramFiles%\dotnet\dotnet.exe" + ) +) + +rem WinUI NuGet package's Microsoft.WinUI.AppX.targets attempts to import a file that does not exist, even when +rem executing "dotnet test --no-build ...", which evidently still needs to parse and load the entire project. +rem Work around by using a dummy targets file and assigning it to the MsAppxPackageTargets property. +echo ^ > %temp%\EmptyMsAppxPackage.Targets +call :exec %dotnet_exe% test --verbosity normal --no-build --logger xunit;LogFilePath=%~dp0unittest_%cswinrt_version_string%.xml %this_dir%Tests/unittest/UnitTest.csproj /nologo /m /p:platform=%cswinrt_platform%;configuration=%cswinrt_configuration%;MsAppxPackageTargets=%temp%\EmptyMsAppxPackage.Targets +if ErrorLevel 1 ( + echo. + echo ERROR: Unit test failed, skipping NuGet pack + exit /b !ErrorLevel! +) + +:hosttest +rem Run WinRT.Host tests +echo Running cswinrt host tests for %cswinrt_platform% %cswinrt_configuration% +call :exec %this_dir%_build\%cswinrt_platform%\%cswinrt_configuration%\HostTest\bin\HostTest.exe --gtest_output=xml:%this_dir%hosttest_%cswinrt_version_string%.xml +if ErrorLevel 1 ( + echo. + echo ERROR: Host test failed, skipping NuGet pack + exit /b !ErrorLevel! +) + +:authortest +rem Run Authoring tests +echo Running cswinrt authoring tests for %cswinrt_platform% %cswinrt_configuration% +call :exec %this_dir%_build\%cswinrt_platform%\%cswinrt_configuration%\AuthoringConsumptionTest\bin\AuthoringConsumptionTest.exe --gtest_output=xml:%this_dir%hosttest_%cswinrt_version_string%.xml +if ErrorLevel 1 ( + echo. + echo ERROR: Authoring test failed, skipping NuGet pack + exit /b !ErrorLevel! +) + +:package +set cswinrt_bin_dir=%this_dir%_build\%cswinrt_platform%\%cswinrt_configuration%\cswinrt\bin\ +set cswinrt_exe=%cswinrt_bin_dir%cswinrt.exe +set netstandard2_runtime=%this_dir%WinRT.Runtime\bin\%cswinrt_configuration%\netstandard2.0\WinRT.Runtime.dll +set net5_runtime=%this_dir%WinRT.Runtime\bin\%cswinrt_configuration%\net5.0\WinRT.Runtime.dll +set source_generator=%this_dir%Authoring\WinRT.SourceGenerator\bin\%cswinrt_configuration%\netstandard2.0\WinRT.SourceGenerator.dll +set winrt_host_%cswinrt_platform%=%this_dir%_build\%cswinrt_platform%\%cswinrt_configuration%\WinRT.Host\bin\WinRT.Host.dll +set winrt_shim=%this_dir%Authoring\WinRT.Host.Shim\bin\%cswinrt_configuration%\net5.0\WinRT.Host.Shim.dll +set guid_patch=%this_dir%Perf\GuidPatch\bin\%cswinrt_platform%\%cswinrt_configuration%\net5.0\GuidPatch.exe +echo Creating nuget package +call :exec %nuget_dir%\nuget pack %this_dir%..\nuget\Microsoft.Windows.CsWinRT.nuspec -Properties cswinrt_exe=%cswinrt_exe%;netstandard2_runtime=%netstandard2_runtime%;net5_runtime=%net5_runtime%;source_generator=%source_generator%;cswinrt_nuget_version=%cswinrt_version_string%;winrt_host_x86=%winrt_host_x86%;winrt_host_x64=%winrt_host_x64%;winrt_host_arm=%winrt_host_arm%;winrt_host_arm64=%winrt_host_arm64%;winrt_shim=%winrt_shim%;guid_patch=%guid_patch% -OutputDirectory %cswinrt_bin_dir% -NonInteractive -Verbosity Detailed -NoPackageAnalysis +goto :eof + +:exec +if /i "%cswinrt_echo%" == "only" ( +echo Command Line: +echo %* +echo. +) else ( +%* +) +goto :eof From 2f3128c025f982ac145a49c6d26da42bc03ba3f1 Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Tue, 25 May 2021 16:59:23 -0700 Subject: [PATCH 06/24] Remove platform based logic, only run in net5, other fixes --- nuget/Microsoft.Windows.CsWinRT.targets | 20 +- src/Perf/IIDOptimizer/IIDOptimizer.csproj | 1 - src/Projections/Benchmark/Benchmark.csproj | 4 + src/Projections/Test/Test.csproj | 4 + .../TestHost.ProbeByClass.csproj | 4 + src/Projections/WinUI/WinUI.csproj | 4 + src/Projections/Windows/Windows.csproj | 4 + .../AuthoringWinUITest/App.xaml.cpp | 1 - src/build.cmd | 1 + src/cswinrt.sln | 15 +- src/quickbuild.cmd | 191 ------------------ 11 files changed, 42 insertions(+), 207 deletions(-) delete mode 100644 src/quickbuild.cmd diff --git a/nuget/Microsoft.Windows.CsWinRT.targets b/nuget/Microsoft.Windows.CsWinRT.targets index 1aab5764b..a2ff91198 100644 --- a/nuget/Microsoft.Windows.CsWinRT.targets +++ b/nuget/Microsoft.Windows.CsWinRT.targets @@ -147,12 +147,11 @@ $(CsWinRTFilters) - - - - - - + + @@ -162,10 +161,11 @@ $(CsWinRTFilters) $(CsWinRTPath)build\tools\GuidPatch\ $(CsWinRTPath)lib\net5.0\ - - @(BuiltProjectOutputGroupKeyOutput->'%(Identity)') + @(BuiltProjectOutputGroupKeyOutput->'%(Identity)') + + $([System.IO.Directory]::GetParent($(CsWinRTIIDOptimizerInput))) - + @@ -176,7 +176,7 @@ $(CsWinRTFilters) - + diff --git a/src/Perf/IIDOptimizer/IIDOptimizer.csproj b/src/Perf/IIDOptimizer/IIDOptimizer.csproj index 3d9a8f99a..bc07a8798 100644 --- a/src/Perf/IIDOptimizer/IIDOptimizer.csproj +++ b/src/Perf/IIDOptimizer/IIDOptimizer.csproj @@ -4,7 +4,6 @@ Exe net5.0 enable - AnyCPU diff --git a/src/Projections/Benchmark/Benchmark.csproj b/src/Projections/Benchmark/Benchmark.csproj index dc5dc1a5f..53c3a6ca8 100644 --- a/src/Projections/Benchmark/Benchmark.csproj +++ b/src/Projections/Benchmark/Benchmark.csproj @@ -5,6 +5,10 @@ x64;x86 + + true + + diff --git a/src/Projections/Test/Test.csproj b/src/Projections/Test/Test.csproj index ad43fb7d5..f1943b757 100644 --- a/src/Projections/Test/Test.csproj +++ b/src/Projections/Test/Test.csproj @@ -5,6 +5,10 @@ x64;x86 + + true + + diff --git a/src/Projections/TestHost.ProbeByClass/TestHost.ProbeByClass.csproj b/src/Projections/TestHost.ProbeByClass/TestHost.ProbeByClass.csproj index 16f85c34a..5204fce19 100644 --- a/src/Projections/TestHost.ProbeByClass/TestHost.ProbeByClass.csproj +++ b/src/Projections/TestHost.ProbeByClass/TestHost.ProbeByClass.csproj @@ -5,6 +5,10 @@ x64;x86 + + true + + diff --git a/src/Projections/WinUI/WinUI.csproj b/src/Projections/WinUI/WinUI.csproj index 3228b7d65..b5984b310 100644 --- a/src/Projections/WinUI/WinUI.csproj +++ b/src/Projections/WinUI/WinUI.csproj @@ -5,6 +5,10 @@ x64;x86 + + true + + diff --git a/src/Projections/Windows/Windows.csproj b/src/Projections/Windows/Windows.csproj index f0e9d5265..1e2fb5c3f 100644 --- a/src/Projections/Windows/Windows.csproj +++ b/src/Projections/Windows/Windows.csproj @@ -5,6 +5,10 @@ x64;x86 + + true + + diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/App.xaml.cpp b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/App.xaml.cpp index 91cc89511..22e677eb5 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/App.xaml.cpp +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/App.xaml.cpp @@ -26,7 +26,6 @@ using namespace AuthoringWinUITest::implementation; App::App() { InitializeComponent(); - Suspending({ this, &App::OnSuspending }); #if defined _DEBUG && !defined DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION UnhandledException([this](IInspectable const&, UnhandledExceptionEventArgs const& e) diff --git a/src/build.cmd b/src/build.cmd index d9ca387da..e8f4d7c47 100644 --- a/src/build.cmd +++ b/src/build.cmd @@ -186,6 +186,7 @@ set source_generator=%this_dir%Authoring\WinRT.SourceGenerator\bin\%cswinrt_conf set winrt_host_%cswinrt_platform%=%this_dir%_build\%cswinrt_platform%\%cswinrt_configuration%\WinRT.Host\bin\WinRT.Host.dll set winrt_shim=%this_dir%Authoring\WinRT.Host.Shim\bin\%cswinrt_configuration%\net5.0\WinRT.Host.Shim.dll set guid_patch=%this_dir%Perf\IIDOptimizer\bin\%cswinrt_configuration%\net5.0\*.* + echo Creating nuget package call :exec %nuget_dir%\nuget pack %this_dir%..\nuget\Microsoft.Windows.CsWinRT.nuspec -Properties cswinrt_exe=%cswinrt_exe%;netstandard2_runtime=%netstandard2_runtime%;net5_runtime=%net5_runtime%;source_generator=%source_generator%;cswinrt_nuget_version=%cswinrt_version_string%;winrt_host_x86=%winrt_host_x86%;winrt_host_x64=%winrt_host_x64%;winrt_host_arm=%winrt_host_arm%;winrt_host_arm64=%winrt_host_arm64%;winrt_shim=%winrt_shim%;guid_patch=%guid_patch% -OutputDirectory %cswinrt_bin_dir% -NonInteractive -Verbosity Detailed -NoPackageAnalysis goto :eof diff --git a/src/cswinrt.sln b/src/cswinrt.sln index 57e0e2f1f..138b8f270 100644 --- a/src/cswinrt.sln +++ b/src/cswinrt.sln @@ -8,6 +8,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestComponentCSharp", "Test EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "Tests\UnitTest\UnitTest.csproj", "{9A9F52CA-F624-43A4-B5EF-C50861F584C2}" + ProjectSection(ProjectDependencies) = postProject + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9} = {AE3B0611-2FBB-42AB-A245-B4E79868A5F9} + {25244CED-966E-45F2-9711-1F51E951FF89} = {25244CED-966E-45F2-9711-1F51E951FF89} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cswinrt", "cswinrt\cswinrt.vcxproj", "{6ACFD2B2-E8AA-4CD4-AAD8-213CE8BB2637}" ProjectSection(ProjectDependencies) = postProject @@ -102,6 +106,9 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Perf", "Perf", "{539DBDEF-3B49-4503-9BD3-7EB83C2179CB}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IIDOptimizer", "Perf\IIDOptimizer\IIDOptimizer.csproj", "{AE3B0611-2FBB-42AB-A245-B4E79868A5F9}" + ProjectSection(ProjectDependencies) = postProject + {25244CED-966E-45F2-9711-1F51E951FF89} = {25244CED-966E-45F2-9711-1F51E951FF89} + EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -362,10 +369,10 @@ Global {493C7729-2F21-4198-AB09-BDF56BF501D3}.Release|x86.Build.0 = Release|Win32 {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|x64.ActiveCfg = Debug|x64 - {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|x64.Build.0 = Debug|x64 - {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|x86.ActiveCfg = Debug|x86 - {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|x86.Build.0 = Debug|x86 + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|x64.ActiveCfg = Debug|Any CPU + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|x64.Build.0 = Debug|Any CPU + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|x86.ActiveCfg = Debug|Any CPU + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|x86.Build.0 = Debug|Any CPU {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Release|Any CPU.ActiveCfg = Release|Any CPU {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Release|Any CPU.Build.0 = Release|Any CPU {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Release|x64.ActiveCfg = Release|Any CPU diff --git a/src/quickbuild.cmd b/src/quickbuild.cmd deleted file mode 100644 index 4bd09048a..000000000 --- a/src/quickbuild.cmd +++ /dev/null @@ -1,191 +0,0 @@ -@echo off -if /i "%cswinrt_echo%" == "on" @echo on - -set CsWinRTNet5SdkVersion=5.0.100 - -set this_dir=%~dp0 - -:dotnet -rem Install required .NET 5 SDK version and add to environment -set DOTNET_ROOT=%LocalAppData%\Microsoft\dotnet -set DOTNET_ROOT(86)=%LocalAppData%\Microsoft\dotnet\x86 -set path=%DOTNET_ROOT%;%path% - -:globaljson -rem Create global.json for current .NET SDK, and with allowPrerelease=true -set global_json=%this_dir%global.json -echo { > %global_json% -echo "sdk": { >> %global_json% -echo "version": "%CsWinRTNet5SdkVersion%", >> %global_json% -echo "allowPrerelease": true >> %global_json% -echo } >> %global_json% -echo } >> %global_json% - -rem Preserve above for Visual Studio launch inheritance -setlocal ENABLEDELAYEDEXPANSION - -:params -set cswinrt_platform=%1 -set cswinrt_configuration=%2 -set cswinrt_version_number=%3 -set cswinrt_version_string=%4 -set cswinrt_assembly_version=%5 -set "%6"!="" set cswinrt_label=%6 - -if "%cswinrt_platform%"=="" set cswinrt_platform=x64 - -if /I "%cswinrt_platform%" equ "all" ( - if "%cswinrt_configuration%"=="" ( - set cswinrt_configuration=all - ) - call %0 x86 !cswinrt_configuration! !cswinrt_version_number! !cswinrt_version_string! !cswinrt_assembly_version! - call %0 x64 !cswinrt_configuration! !cswinrt_version_number! !cswinrt_version_string! !cswinrt_assembly_version! - call %0 arm !cswinrt_configuration! !cswinrt_version_number! !cswinrt_version_string! !cswinrt_assembly_version! - call %0 arm64 !cswinrt_configuration! !cswinrt_version_number! !cswinrt_version_string! !cswinrt_assembly_version! - goto :eof -) - -if /I "%cswinrt_configuration%" equ "all" ( - call %0 %cswinrt_platform% Debug !cswinrt_version_number! !cswinrt_version_string! !cswinrt_assembly_version! - call %0 %cswinrt_platform% Release !cswinrt_version_number! !cswinrt_version_string! !cswinrt_assembly_version! - goto :eof -) - -if "%cswinrt_configuration%"=="" ( - set cswinrt_configuration=Release -) - -if "%cswinrt_version_number%"=="" set cswinrt_version_number=0.0.0.0 -if "%cswinrt_version_string%"=="" set cswinrt_version_string=0.0.0-private.0 -if "%cswinrt_assembly_version%"=="" set cswinrt_assembly_version=0.0.0.0 - -if "%cswinrt_baseline_breaking_compat_errors%"=="" set cswinrt_baseline_breaking_compat_errors=false -if "%cswinrt_baseline_assembly_version_compat_errors%"=="" set cswinrt_baseline_assembly_version_compat_errors=false - -rem Generate prerelease targets file to exercise build warnings -set prerelease_targets=%this_dir%..\nuget\Microsoft.Windows.CsWinRT.Prerelease.targets -rem Create default %prerelease_targets% -echo ^ > %prerelease_targets% -echo ^> %prerelease_targets% -echo Condition="'$(NetCoreSdkVersion)' ^!= '%CsWinRTNet5SdkVersion%' and '$(Net5SdkVersion)' ^!= '%CsWinRTNet5SdkVersion%'"^> >> %prerelease_targets% -echo ^ >> %prerelease_targets% -echo ^ >> %prerelease_targets% -echo ^ >> %prerelease_targets% - -goto :skip_build_tools -rem VS 16.X BuildTools support (when a prerelease VS is required, until it is deployed to Azure Devops agents) -msbuild -ver | findstr 16.X >nul -if ErrorLevel 1 ( - echo Using VS Build Tools 16.X - if %cswinrt_platform%==x86 ( - set msbuild_path="%this_dir%.buildtools\MSBuild\Current\Bin\\" - ) else ( - set msbuild_path="%this_dir%.buildtools\MSBuild\Current\Bin\amd64\\" - ) - if not exist !msbuild_path! ( - if not exist .buildtools md .buildtools - powershell -NoProfile -ExecutionPolicy unrestricted -File .\get_buildtools.ps1 - ) - set nuget_params=-MSBuildPath !msbuild_path! -) else ( - set msbuild_path= - set nuget_params= -) -:skip_build_tools - -if not "%cswinrt_label%"=="" goto %cswinrt_label% - -:restore -rem When a preview nuget is required, update -self doesn't work, so manually update -set nuget_dir=%this_dir%.nuget -if exist %nuget_dir%\nuget.exe ( - %nuget_dir%\nuget.exe | findstr 5.8.0 >nul - if ErrorLevel 1 ( - echo Updating to nuget 5.8.0 - rd /s/q %nuget_dir% >nul 2>&1 - ) -) -if not exist %nuget_dir% md %nuget_dir% -if not exist %nuget_dir%\nuget.exe powershell -Command "Invoke-WebRequest https://dist.nuget.org/win-x86-commandline/v5.8.0-preview.2/nuget.exe -OutFile %nuget_dir%\nuget.exe" -%nuget_dir%\nuget update -self -rem Note: packages.config-based (vcxproj) projects do not support msbuild /t:restore -call %this_dir%get_testwinrt.cmd -call :exec %nuget_dir%\nuget.exe restore %nuget_params% %this_dir%cswinrt.sln - -:build -echo Building cswinrt for %cswinrt_platform% %cswinrt_configuration% -call :exec %msbuild_path%msbuild.exe %cswinrt_build_params% /p:platform=%cswinrt_platform%;configuration=%cswinrt_configuration%;VersionNumber=%cswinrt_version_number%;VersionString=%cswinrt_version_string%;AssemblyVersionNumber=%cswinrt_assembly_version%;GenerateTestProjection=true;BaselineAllAPICompatError=%cswinrt_baseline_breaking_compat_errors%;BaselineAllMatchingRefApiCompatError=%cswinrt_baseline_assembly_version_compat_errors% %this_dir%cswinrt.sln -if ErrorLevel 1 ( - echo. - echo ERROR: Build failed - exit /b !ErrorLevel! -) -if "%cswinrt_build_only%"=="true" goto :eof -if "%cswinrt_buildpack%"=="true" goto :package - -:test -:unittest -rem Build/Run xUnit tests, generating xml output report for Azure Devops reporting, via XunitXml.TestLogger NuGet -echo Running cswinrt unit tests for %cswinrt_platform% %cswinrt_configuration% -set dotnet_exe="%DOTNET_ROOT%\dotnet.exe" -if not exist %dotnet_exe% ( - if %cswinrt_platform%==x86 ( - set dotnet_exe="%ProgramFiles(x86)%\dotnet\dotnet.exe" - ) else ( - set dotnet_exe="%ProgramFiles%\dotnet\dotnet.exe" - ) -) - -rem WinUI NuGet package's Microsoft.WinUI.AppX.targets attempts to import a file that does not exist, even when -rem executing "dotnet test --no-build ...", which evidently still needs to parse and load the entire project. -rem Work around by using a dummy targets file and assigning it to the MsAppxPackageTargets property. -echo ^ > %temp%\EmptyMsAppxPackage.Targets -call :exec %dotnet_exe% test --verbosity normal --no-build --logger xunit;LogFilePath=%~dp0unittest_%cswinrt_version_string%.xml %this_dir%Tests/unittest/UnitTest.csproj /nologo /m /p:platform=%cswinrt_platform%;configuration=%cswinrt_configuration%;MsAppxPackageTargets=%temp%\EmptyMsAppxPackage.Targets -if ErrorLevel 1 ( - echo. - echo ERROR: Unit test failed, skipping NuGet pack - exit /b !ErrorLevel! -) - -:hosttest -rem Run WinRT.Host tests -echo Running cswinrt host tests for %cswinrt_platform% %cswinrt_configuration% -call :exec %this_dir%_build\%cswinrt_platform%\%cswinrt_configuration%\HostTest\bin\HostTest.exe --gtest_output=xml:%this_dir%hosttest_%cswinrt_version_string%.xml -if ErrorLevel 1 ( - echo. - echo ERROR: Host test failed, skipping NuGet pack - exit /b !ErrorLevel! -) - -:authortest -rem Run Authoring tests -echo Running cswinrt authoring tests for %cswinrt_platform% %cswinrt_configuration% -call :exec %this_dir%_build\%cswinrt_platform%\%cswinrt_configuration%\AuthoringConsumptionTest\bin\AuthoringConsumptionTest.exe --gtest_output=xml:%this_dir%hosttest_%cswinrt_version_string%.xml -if ErrorLevel 1 ( - echo. - echo ERROR: Authoring test failed, skipping NuGet pack - exit /b !ErrorLevel! -) - -:package -set cswinrt_bin_dir=%this_dir%_build\%cswinrt_platform%\%cswinrt_configuration%\cswinrt\bin\ -set cswinrt_exe=%cswinrt_bin_dir%cswinrt.exe -set netstandard2_runtime=%this_dir%WinRT.Runtime\bin\%cswinrt_configuration%\netstandard2.0\WinRT.Runtime.dll -set net5_runtime=%this_dir%WinRT.Runtime\bin\%cswinrt_configuration%\net5.0\WinRT.Runtime.dll -set source_generator=%this_dir%Authoring\WinRT.SourceGenerator\bin\%cswinrt_configuration%\netstandard2.0\WinRT.SourceGenerator.dll -set winrt_host_%cswinrt_platform%=%this_dir%_build\%cswinrt_platform%\%cswinrt_configuration%\WinRT.Host\bin\WinRT.Host.dll -set winrt_shim=%this_dir%Authoring\WinRT.Host.Shim\bin\%cswinrt_configuration%\net5.0\WinRT.Host.Shim.dll -set guid_patch=%this_dir%Perf\GuidPatch\bin\%cswinrt_platform%\%cswinrt_configuration%\net5.0\GuidPatch.exe -echo Creating nuget package -call :exec %nuget_dir%\nuget pack %this_dir%..\nuget\Microsoft.Windows.CsWinRT.nuspec -Properties cswinrt_exe=%cswinrt_exe%;netstandard2_runtime=%netstandard2_runtime%;net5_runtime=%net5_runtime%;source_generator=%source_generator%;cswinrt_nuget_version=%cswinrt_version_string%;winrt_host_x86=%winrt_host_x86%;winrt_host_x64=%winrt_host_x64%;winrt_host_arm=%winrt_host_arm%;winrt_host_arm64=%winrt_host_arm64%;winrt_shim=%winrt_shim%;guid_patch=%guid_patch% -OutputDirectory %cswinrt_bin_dir% -NonInteractive -Verbosity Detailed -NoPackageAnalysis -goto :eof - -:exec -if /i "%cswinrt_echo%" == "only" ( -echo Command Line: -echo %* -echo. -) else ( -%* -) -goto :eof From a2ff6b6f4586d12c9a743fe828e0a6e667c6c482 Mon Sep 17 00:00:00 2001 From: Manodasan Date: Mon, 31 May 2021 21:36:53 -0700 Subject: [PATCH 07/24] Fix GUID patcher to pass tests. --- src/Perf/IIDOptimizer/GuidPatcher.cs | 3 +- src/Perf/IIDOptimizer/SignatureEmitter.cs | 28 ++- .../build/Microsoft.WinUI.AppX.targets | 188 +++++++++++------- 3 files changed, 139 insertions(+), 80 deletions(-) diff --git a/src/Perf/IIDOptimizer/GuidPatcher.cs b/src/Perf/IIDOptimizer/GuidPatcher.cs index 00e7e82cb..88830942d 100644 --- a/src/Perf/IIDOptimizer/GuidPatcher.cs +++ b/src/Perf/IIDOptimizer/GuidPatcher.cs @@ -68,7 +68,8 @@ public GuidPatcher(string assemblyPath, IAssemblyResolver assemblyResolver, Asse { new ParameterDefinition(new PointerType(assembly.MainModule.TypeSystem.Void)), new ParameterDefinition(assembly.MainModule.TypeSystem.Int32), - } + }, + HasThis = true }); guidCtor = assembly.MainModule.ImportReference(guidType.Methods.First(m => m.IsConstructor && m.Parameters.Count == 1 && m.Parameters[0].ParameterType.Resolve() == readOnlySpanOfByte.Resolve())); diff --git a/src/Perf/IIDOptimizer/SignatureEmitter.cs b/src/Perf/IIDOptimizer/SignatureEmitter.cs index f0722b783..7f3b28f01 100644 --- a/src/Perf/IIDOptimizer/SignatureEmitter.cs +++ b/src/Perf/IIDOptimizer/SignatureEmitter.cs @@ -110,14 +110,28 @@ private void GenerateGuidFromSimpleSignature(StringStep stringStep, TypeDefiniti Span hash = stackalloc byte[160]; SHA1.HashData(data, hash); - // Encode rfc time/version/clock/reserved fields - hash[8] = (byte)((hash[8] & 0x3f) | 0x80); + if (BitConverter.IsLittleEndian) + { + // swap bytes of int a + byte t = hash[0]; + hash[0] = hash[3]; + hash[3] = t; + t = hash[1]; + hash[1] = hash[2]; + hash[2] = t; + // swap bytes of short b + t = hash[4]; + hash[4] = hash[5]; + hash[5] = t; + // swap bytes of short c and encode rfc time/version field + t = hash[6]; + hash[6] = hash[7]; + hash[7] = (byte)((t & 0x0f) | (5 << 4)); + // encode rfc clock/reserved field + hash[8] = (byte)((hash[8] & 0x3f) | 0x80); + } - var iid = new Guid( - BinaryPrimitives.ReadInt32BigEndian(hash[0..4]), - BinaryPrimitives.ReadInt16BigEndian(hash[4..6]), - (short)((BinaryPrimitives.ReadInt16BigEndian(hash[6..8]) & 0xff0f) | (5 << 4)), - hash[8..16].ToArray()); + var iid = new Guid(hash[0..16]); CecilExtensions.WriteIIDDataGetterBody(guidDataGetterMethod, describedType, iid, guidDataBlockType, implementationDetailsType, readOnlySpanOfByteCtor); } diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest (Package)/build/Microsoft.WinUI.AppX.targets b/src/Tests/AuthoringWinUITest/AuthoringWinUITest (Package)/build/Microsoft.WinUI.AppX.targets index 307641788..b88f956f5 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest (Package)/build/Microsoft.WinUI.AppX.targets +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest (Package)/build/Microsoft.WinUI.AppX.targets @@ -35,6 +35,7 @@ + @@ -152,6 +157,19 @@ + + + true + + $(MSBuildWarningsAsMessages); + MSB3842; + MSB3843; + + + @@ -187,6 +205,22 @@ + + + + + + $(OutDir)%(_FilteredNonWapProjProjectOutput.DestinationSubDirectory)%(Filename)%(Extension) + + + $(OutDir)%(_FilteredNonWapProjProjectOutput.DestinationSubDirectory)%(Filename)%(Extension) + + + - - - - + + + true + - - + - + + + + + + + + true + + - - - - - UAP - - + + + net5.0-windows$(TargetPlatformVersion);$(AssetTargetFallback) + + + + + + From 7e5df52a01bdc176d3a17dcbe8f5242fe8d27c02 Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Tue, 8 Jun 2021 14:54:25 -0700 Subject: [PATCH 08/24] Avoid invalid cast exception, props changes, some cleanup --- nuget/Microsoft.Windows.CsWinRT.targets | 23 +- src/Perf/IIDOptimizer/GuidPatcher.cs | 266 ++++++++++------- src/Perf/IIDOptimizer/Logger.cs | 36 +++ src/Perf/IIDOptimizer/Program.cs | 8 +- src/Perf/IIDOptimizer/SignatureEmitter.cs | 28 +- src/Perf/IIDOptimizer/SignatureGenerator.cs | 28 +- src/Projections/Benchmark/Benchmark.csproj | 4 - src/Projections/Directory.Build.props | 6 +- src/Projections/Test/Test.csproj | 4 - .../TestHost.ProbeByClass.csproj | 4 - src/Projections/WinUI/WinUI.csproj | 4 - src/Projections/Windows/Windows.csproj | 4 - src/Tests/AuthoringTest/AuthoringTest.csproj | 1 - .../AuthoringWinUITest (Package).wapproj | 2 - .../build/Microsoft.WinUI.AppX.targets | 280 ------------------ .../AuthoringWinUITest.vcxproj | 30 +- .../AuthoringWinUITest.vcxproj.filters | 1 + .../Directory.Build.targets | 4 +- .../AuthoringWinUITest/packages.config | 9 +- .../Directory.Build.targets | 10 + .../DiagnosticTests/DiagnosticTests.csproj | 1 - src/Tests/UnitTest/UnitTest.csproj | 1 - 22 files changed, 294 insertions(+), 460 deletions(-) create mode 100644 src/Perf/IIDOptimizer/Logger.cs delete mode 100644 src/Tests/AuthoringWinUITest/AuthoringWinUITest (Package)/build/Microsoft.WinUI.AppX.targets diff --git a/nuget/Microsoft.Windows.CsWinRT.targets b/nuget/Microsoft.Windows.CsWinRT.targets index a2ff91198..7704363f5 100644 --- a/nuget/Microsoft.Windows.CsWinRT.targets +++ b/nuget/Microsoft.Windows.CsWinRT.targets @@ -155,26 +155,29 @@ $(CsWinRTFilters) - $(CsWinRTIIDOptimizerPath) - $(CsWinRTIIDOptimizerRuntimePath) - - $(CsWinRTPath)build\tools\GuidPatch\ - $(CsWinRTPath)lib\net5.0\ - + $(CsWinRTPath)build\tools\GuidPatch\ + $(CsWinRTPath)lib\net5.0\ @(BuiltProjectOutputGroupKeyOutput->'%(Identity)') - $([System.IO.Directory]::GetParent($(CsWinRTIIDOptimizerInput))) - + + + + + + - + diff --git a/src/Perf/IIDOptimizer/GuidPatcher.cs b/src/Perf/IIDOptimizer/GuidPatcher.cs index 88830942d..93d0bc980 100644 --- a/src/Perf/IIDOptimizer/GuidPatcher.cs +++ b/src/Perf/IIDOptimizer/GuidPatcher.cs @@ -29,9 +29,24 @@ class GuidPatcher private readonly TypeDefinition guidImplementationDetailsType; private readonly TypeDefinition guidDataBlockType; private SignatureGenerator signatureGenerator; + private Logger Logger { get; } + + // OptimizerDir is the path our current process should use to write logs and patched DLLs to + public string OptimizerDir + { + get { return "obj\\IIDOptimizer"; } + } public GuidPatcher(string assemblyPath, IAssemblyResolver assemblyResolver, AssemblyDefinition winRTRuntime) { + /* + * Initialize the logger with the OptimizerDir property + */ + Logger = new Logger(OptimizerDir, "log.txt"); + + /* + * Initialize readonly fields + */ assembly = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters(ReadingMode.Deferred) { ReadWrite = true, @@ -42,7 +57,6 @@ public GuidPatcher(string assemblyPath, IAssemblyResolver assemblyResolver, Asse ApplyWindowsRuntimeProjections = false }); - winRTRuntimeAssembly = winRTRuntime; // assemblyResolver.Resolve(new AssemblyNameReference("WinRT.Runtime", default)); guidImplementationDetailsType = new TypeDefinition(null, "", TypeAttributes.AutoClass | TypeAttributes.Sealed, assembly.MainModule.TypeSystem.Object); @@ -110,6 +124,8 @@ public int ProcessAssembly() { return 0; } + + Logger.Log($"Processing assembly: {assembly}."); int numPatches = 0; var methods = from module in assembly.Modules from type in module.Types @@ -122,6 +138,7 @@ where method.HasBody numPatches += ProcessMethodBody(method.Body, getTypeFromHandleMethod, getIidMethod!, createIidMethod!); } + Logger.Close(); return numPatches; } @@ -138,116 +155,13 @@ enum State GetHelperTypeOptional } - private int ProcessMethodBody(MethodBody body, MethodDefinition getTypeFromHandleMethod, MethodDefinition getIidMethod, MethodDefinition createIidMethod) - { - int numberOfReplacements = 0; - TypeReference? type = null; - State state = State.Start; - int startIlIndex = -1; - int numberOfInstructionsToOverwrite = 3; - for (int i = 0; i < body.Instructions.Count; i++) - { - var instruction = body.Instructions[i]; - switch (state) - { - case State.Start: - if (instruction.OpCode.Code != Code.Ldtoken) - { - continue; - } - var typeMaybe = (TypeReference)instruction.Operand; - if (!typeMaybe.IsGenericParameter) - { - state = State.Ldtoken; - type = typeMaybe; - startIlIndex = i; - } - break; - case State.Ldtoken: - { - if (instruction.OpCode.Code != Code.Call) - { - state = State.Start; - type = null; - continue; - } - var method = ((MethodReference)instruction.Operand).Resolve(); - if (method == getTypeFromHandleMethod) - { - state = State.GetTypeFromHandle; - } - } - break; - case State.GetTypeFromHandle: - { - if (instruction.OpCode.Code != Code.Call) - { - state = State.Start; - type = null; - continue; - } - var method = ((MethodReference)instruction.Operand).Resolve(); - if (method == getHelperTypeMethod) - { - numberOfInstructionsToOverwrite++; - state = State.GetHelperTypeOptional; - continue; - } - else - { - goto case State.GetHelperTypeOptional; - } - } - case State.GetHelperTypeOptional: - { - if (instruction.OpCode.Code != Code.Call) - { - state = State.Start; - type = null; - continue; - } - var method = ((MethodReference)instruction.Operand).Resolve(); - if (method == getIidMethod || method == createIidMethod) - { - try - { - bool didPatch = false; - if (type!.IsGenericInstance) - { - didPatch = PatchGenericTypeIID(body, startIlIndex, type, numberOfInstructionsToOverwrite); - } - else - { - didPatch = PatchNonGenericTypeIID(body, startIlIndex, type, numberOfInstructionsToOverwrite); - } - - if (didPatch) - { - numberOfReplacements++; - } - } - catch (Exception ex) - { - Debug.WriteLine($"Exception thrown during patching {body.Method.FullName}: {ex}"); - } - } - else - { - state = State.Start; - type = null; - startIlIndex = -1; - } - } - break; - default: - throw new InvalidOperationException(); - } - } - return numberOfReplacements; - } - private bool PatchNonGenericTypeIID(MethodBody body, int startILIndex, TypeReference type, int numberOfInstructionsToOverwrite) { + /* + Logger.Log($"PatchNonGenericTypeIID"); + Logger.Log($"\tbody.Method = {body.Method}."); + Logger.Log($"\ttype = {type}."); + */ if (numberOfInstructionsToOverwrite < 2) { return false; @@ -274,13 +188,18 @@ private bool PatchNonGenericTypeIID(MethodBody body, int startILIndex, TypeRefer private bool PatchGenericTypeIID(MethodBody body, int startILIndex, TypeReference type, int numberOfInstructionsToOverwrite) { + /* + Logger.Log($"PatchGenericTypeIID:"); + Logger.Log($"\tbody.Method = {body.Method}."); + Logger.Log($"\ttype = {type}."); + */ SignaturePart rootSignaturePart = signatureGenerator.GetSignatureParts(type); var guidDataMethod = new MethodDefinition($"{type.FullName}", MethodAttributes.Assembly | MethodAttributes.Static, readOnlySpanOfByte); guidImplementationDetailsType.Methods.Add(guidDataMethod); - var emitter = new SignatureEmitter(type, guidDataMethod); + var emitter = new SignatureEmitter(type, guidDataMethod, Logger); VisitSignature(rootSignaturePart, emitter); emitter.EmitGuidGetter(guidDataBlockType, guidImplementationDetailsType, readOnlySpanOfByte, readOnlySpanOfByteCtor, guidGeneratorType!); @@ -302,6 +221,11 @@ private bool PatchGenericTypeIID(MethodBody body, int startILIndex, TypeReferenc private void ReplaceWithCallToGuidDataGetter(MethodBody body, int startILIndex, int numberOfInstructionsToOverwrite, MethodReference guidDataMethod) { + /* + Logger.Log($"ReplaceWithCallToGuidDataGetter:"); + Logger.Log($"\tMethodBody = {body}."); + Logger.Log($"\tguidDataMethod = {guidDataMethod}."); + */ var il = body.GetILProcessor(); il.Replace(startILIndex, Instruction.Create(OpCodes.Call, guidDataMethod)); il.Replace(startILIndex + 1, Instruction.Create(OpCodes.Newobj, guidCtor)); @@ -313,10 +237,13 @@ private void ReplaceWithCallToGuidDataGetter(MethodBody body, int startILIndex, private void VisitSignature(SignaturePart rootSignaturePart, SignatureEmitter emitter) { + Logger.Log("VisitSignature"); + Logger.Log($"emitter: {emitter}"); switch (rootSignaturePart) { case BasicSignaturePart basic: { + Logger.TLog("(1)"); emitter.PushString(basic.Type switch { SignatureType.@string => "string", @@ -327,6 +254,7 @@ private void VisitSignature(SignaturePart rootSignaturePart, SignatureEmitter em break; case SignatureWithChildren group: { + Logger.TLog("(2)"); emitter.PushString($"{group.GroupingName}("); emitter.PushString(group.ThisEntitySignature); foreach (var item in group.ChildrenSignatures) @@ -339,21 +267,29 @@ private void VisitSignature(SignaturePart rootSignaturePart, SignatureEmitter em break; case GuidSignature guid: { + Logger.TLog("(3)"); emitter.PushString(guid.IID.ToString("B")); } break; case NonGenericDelegateSignature del: { + /// here! doesnt get hit + // Logger.TLog($"(4) NonGenericDelegateSignature = {del}"); + Logger.TLog("(4)"); emitter.PushString($"delegate({del.DelegateIID:B}"); } break; case UninstantiatedGeneric gen: { + Logger.TLog("(5)"); emitter.PushGenericParameter(gen.OriginalGenericParameter); } break; case CustomSignatureMethod custom: { + // Logger.TLog($"(6) CustomSignatureMethod = {custom}"); + /// doesnt get hit + Logger.TLog("(6)"); emitter.PushCustomSignature(custom.Method); } break; @@ -361,5 +297,115 @@ private void VisitSignature(SignaturePart rootSignaturePart, SignatureEmitter em break; } } + + private int ProcessMethodBody(MethodBody body, MethodDefinition getTypeFromHandleMethod, MethodDefinition getIidMethod, MethodDefinition createIidMethod) + { + int numberOfReplacements = 0; + TypeReference? type = null; + State state = State.Start; + int startIlIndex = -1; + int numberOfInstructionsToOverwrite = 3; + for (int i = 0; i < body.Instructions.Count; i++) + { + var instruction = body.Instructions[i]; + switch (state) + { + case State.Start: + if (instruction.OpCode.Code != Code.Ldtoken) + { + continue; + } + // Do safe cast in case we are given a FieldReference and + // skip if so since we dont think we'll get a RuntimeTypeHandle for it + var typeMaybe = instruction.Operand as TypeReference; + if (typeMaybe != null && !typeMaybe.IsGenericParameter) + { + state = State.Ldtoken; + type = typeMaybe; + startIlIndex = i; + } + break; + case State.Ldtoken: + { + if (instruction.OpCode.Code != Code.Call) + { + state = State.Start; + type = null; + continue; + } + var method = ((MethodReference)instruction.Operand).Resolve(); + if (method == getTypeFromHandleMethod) + { + state = State.GetTypeFromHandle; + } + } + break; + case State.GetTypeFromHandle: + { + if (instruction.OpCode.Code != Code.Call) + { + state = State.Start; + type = null; + continue; + } + var method = ((MethodReference)instruction.Operand).Resolve(); + if (method == getHelperTypeMethod) + { + numberOfInstructionsToOverwrite++; + state = State.GetHelperTypeOptional; + continue; + } + else + { + goto case State.GetHelperTypeOptional; + } + } + case State.GetHelperTypeOptional: + { + if (instruction.OpCode.Code != Code.Call) + { + state = State.Start; + type = null; + continue; + } + var method = ((MethodReference)instruction.Operand).Resolve(); + if (method == getIidMethod || method == createIidMethod) + { + try + { + bool didPatch = false; + if (type!.IsGenericInstance) + { + didPatch = PatchGenericTypeIID(body, startIlIndex, type, numberOfInstructionsToOverwrite); + } + else + { + didPatch = PatchNonGenericTypeIID(body, startIlIndex, type, numberOfInstructionsToOverwrite); + } + + if (didPatch) + { + numberOfReplacements++; + } + } + catch (Exception ex) + { + Debug.WriteLine($"Exception thrown during patching {body.Method.FullName}: {ex}"); + } + } + else + { + state = State.Start; + type = null; + startIlIndex = -1; + } + } + break; + default: + throw new InvalidOperationException(); + } + } + return numberOfReplacements; + } } } diff --git a/src/Perf/IIDOptimizer/Logger.cs b/src/Perf/IIDOptimizer/Logger.cs new file mode 100644 index 000000000..e147b4d07 --- /dev/null +++ b/src/Perf/IIDOptimizer/Logger.cs @@ -0,0 +1,36 @@ +using System.IO; + +namespace GuidPatch +{ + class Logger + { + public Logger(string parentDir) + { + string logFile = Path.Combine(parentDir, "log.txt"); + fileLogger = File.CreateText(logFile); + } + public Logger(string parentDir, string fileName) + { + string logFile = Path.Combine(parentDir, fileName); + fileLogger = File.CreateText(logFile); + } + + public void Log(string text) + { + fileLogger?.WriteLine(text); + } + + public void TLog(string text) + { + fileLogger?.WriteLine("\t" + text); + } + + public void Close() + { + fileLogger?.Close(); + } + + private readonly TextWriter fileLogger; + } + +} diff --git a/src/Perf/IIDOptimizer/Program.cs b/src/Perf/IIDOptimizer/Program.cs index 0e1eb9b9e..635f94354 100644 --- a/src/Perf/IIDOptimizer/Program.cs +++ b/src/Perf/IIDOptimizer/Program.cs @@ -22,13 +22,17 @@ static void Main(string[] args) { resolver.AddSearchDirectory(args[1]); AssemblyDefinition winRTRuntimeAssembly = resolver.Resolve(new AssemblyNameReference("WinRT.Runtime", default)); + + Directory.CreateDirectory("obj\\IIDOptimizer"); + var guidPatcher = new GuidPatcher( args[0], resolver, winRTRuntimeAssembly); + + // moved to GuidPAtcher constructor. Directory.CreateDirectory(guidPatcher.OptimizerDir); int numPatches = guidPatcher.ProcessAssembly(); - Directory.CreateDirectory("obj\\IIDOptimizer"); - guidPatcher.SaveAssembly("obj\\IIDOptimizer"); + guidPatcher.SaveAssembly(guidPatcher.OptimizerDir); Console.WriteLine($"{numPatches} IID calculations/fetches patched"); } catch (AssemblyResolutionException) diff --git a/src/Perf/IIDOptimizer/SignatureEmitter.cs b/src/Perf/IIDOptimizer/SignatureEmitter.cs index 7f3b28f01..0cb3a582f 100644 --- a/src/Perf/IIDOptimizer/SignatureEmitter.cs +++ b/src/Perf/IIDOptimizer/SignatureEmitter.cs @@ -20,6 +20,13 @@ sealed class SignatureEmitter private readonly Dictionary getterParameterToOriginalGenericParameterMapping = new(); private readonly TypeReference describedType; private readonly MethodDefinition guidDataGetterMethod; + private Logger Logger { get; set; } + + // OptimizerDir is the path our current process should use to write logs and patched DLLs to + public string OptimizerDir + { + get { return "obj\\IIDOptimizer"; } + } public IReadOnlyDictionary GenericParameterMapping => getterParameterToOriginalGenericParameterMapping; @@ -31,12 +38,19 @@ sealed record RuntimeGenericSignatureStep(GenericParameter OriginalTypeParameter sealed record RuntimeCustomSignatureStep(MethodReference method) : SignatureStep; - public SignatureEmitter(TypeReference describedType, MethodDefinition guidDataGetterMethod) + public SignatureEmitter(TypeReference describedType, MethodDefinition guidDataGetterMethod, Logger logger) { this.describedType = describedType; this.guidDataGetterMethod = guidDataGetterMethod; + + /* + * Initialize the logger with the OptimizerDir property + */ + Logger = logger; // new Logger(OptimizerDir, "emitter.log.txt"); } + public void CloseLogger() { Logger.Close(); } + public void PushString(string str) { if (currentStringBuilder is null) @@ -138,6 +152,11 @@ private void GenerateGuidFromSimpleSignature(StringStep stringStep, TypeDefiniti private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementationDetailsType, TypeReference readOnlySpanOfByte, MethodReference readOnlySpanOfBytePtrCtor, TypeDefinition guidGeneratorType) { + /* + Logger.Log("GenerateGuidFactoryFromComplexSignature"); + Logger.TLog($"implementationDetailsType : {implementationDetailsType}"); + Logger.TLog($"guidGeneratorType : {guidGeneratorType}"); + */ var module = implementationDetailsType.Module; var readOnlySpanOfByteArrayCtor = module.ImportReference( @@ -217,6 +236,8 @@ private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementati { case StringStep(string str): { + // Logger.Log("(1) StringStep"); + // Logger.TLog($"str = {str}"); byte[] segmentBytes = Encoding.UTF8.GetBytes(str); var staticDataField = new FieldDefinition($"", FieldAttributes.Private | FieldAttributes.InitOnly | FieldAttributes.Static | FieldAttributes.HasFieldRVA, CecilExtensions.GetOrCreateDataBlockType(implementationDetailsType, segmentBytes.Length)) { @@ -238,6 +259,8 @@ private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementati break; case RuntimeGenericSignatureStep(_, GenericParameter localTypeParameter): { + // Logger.Log("(2) RuntimeGenericSignatureStep"); + // Logger.TLog($"localTypeParameter = {localTypeParameter}"); // byte[] bytes = Encoding.UTF8.GetBytes(GetSignature(typeof(localTypeParameter))) il.Emit(OpCodes.Call, utf8EncodingGetter); il.Emit(OpCodes.Ldtoken, localTypeParameter); @@ -257,6 +280,9 @@ private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementati break; case RuntimeCustomSignatureStep(MethodReference customSignatureMethod): { + /// not called + // Logger.Log("(3) RuntimeCustomSignatureStep"); + // Logger.TLog($"customSignatureMethod = {customSignatureMethod}"); // byte[] bytes = Encoding.UTF8.GetBytes(customSignatureMethod()) il.Emit(OpCodes.Call, utf8EncodingGetter); il.Emit(OpCodes.Call, customSignatureMethod); diff --git a/src/Perf/IIDOptimizer/SignatureGenerator.cs b/src/Perf/IIDOptimizer/SignatureGenerator.cs index 4eac5e14a..f570fff39 100644 --- a/src/Perf/IIDOptimizer/SignatureGenerator.cs +++ b/src/Perf/IIDOptimizer/SignatureGenerator.cs @@ -29,23 +29,28 @@ enum SignatureType record BasicSignaturePart(SignatureType Type) : SignaturePart; - abstract record SignatureWithChildren(string GroupingName, string ThisEntitySignature, IEnumerable ChildrenSignatures) : SignaturePart; + sealed record GuidSignature(Guid IID) : SignaturePart; - sealed record GenericSignature(Guid BaseGuid, IEnumerable GenericMemberSignatures) : SignatureWithChildren("pinterface", BaseGuid.ToString("B"), GenericMemberSignatures); - sealed record ValueTypeSignature(TypeReference Type, IEnumerable StructFieldSignatures) : SignatureWithChildren("struct", Type.FullName, StructFieldSignatures); + sealed record CustomSignatureMethod(MethodReference Method) : SignaturePart; - sealed record RuntimeClassSignature(TypeReference RuntimeClass, SignaturePart DefaultInterfaceSignature) : SignatureWithChildren("rc", RuntimeClass.FullName, new[] { DefaultInterfaceSignature }); + sealed record NonGenericDelegateSignature(Guid DelegateIID) : SignaturePart; + + sealed record UninstantiatedGeneric(GenericParameter OriginalGenericParameter) : SignaturePart; - sealed record EnumSignature(TypeReference Type, bool IsFlagEnum) : SignatureWithChildren("enum", Type.FullName, new SignaturePart[] { new BasicSignaturePart(IsFlagEnum ? SignatureType.u4 : SignatureType.i4) }); + abstract record SignatureWithChildren(string GroupingName, string ThisEntitySignature, IEnumerable ChildrenSignatures) : SignaturePart; - sealed record NonGenericDelegateSignature(Guid DelegateIID) : SignaturePart; + sealed record GenericSignature(Guid BaseGuid, IEnumerable GenericMemberSignatures) : + SignatureWithChildren("pinterface", BaseGuid.ToString("B"), GenericMemberSignatures); - sealed record GuidSignature(Guid IID) : SignaturePart; + sealed record ValueTypeSignature(TypeReference Type, IEnumerable StructFieldSignatures) : + SignatureWithChildren("struct", Type.FullName, StructFieldSignatures); - sealed record UninstantiatedGeneric(GenericParameter OriginalGenericParameter) : SignaturePart; + sealed record RuntimeClassSignature(TypeReference RuntimeClass, SignaturePart DefaultInterfaceSignature) : + SignatureWithChildren("rc", RuntimeClass.FullName, new[] { DefaultInterfaceSignature }); - sealed record CustomSignatureMethod(MethodReference Method) : SignaturePart; + sealed record EnumSignature(TypeReference Type, bool IsFlagEnum) : + SignatureWithChildren("enum", Type.FullName, new SignaturePart[] { new BasicSignaturePart(IsFlagEnum ? SignatureType.u4 : SignatureType.i4) }); sealed class SignatureGenerator { @@ -53,11 +58,12 @@ sealed class SignatureGenerator private readonly TypeDefinition guidAttributeType; private readonly AssemblyDefinition winRTRuntimeAssembly; - public SignatureGenerator(AssemblyDefinition assembly, TypeDefinition guidAttributeType, AssemblyDefinition winRTRuntimeAssembly) + /* Constructor: paramterized by the projection, the guid type (?), and the winrt.runtime (could use winrt.runtime.dll version 1.2.1 or 1.2.5 */ + public SignatureGenerator(AssemblyDefinition assembly, TypeDefinition guidAttributeType, AssemblyDefinition runtimeAssembly) { this.assembly = assembly; this.guidAttributeType = guidAttributeType; - this.winRTRuntimeAssembly = winRTRuntimeAssembly; + this.winRTRuntimeAssembly = runtimeAssembly; } public SignaturePart GetSignatureParts(TypeReference type) diff --git a/src/Projections/Benchmark/Benchmark.csproj b/src/Projections/Benchmark/Benchmark.csproj index 53c3a6ca8..dc5dc1a5f 100644 --- a/src/Projections/Benchmark/Benchmark.csproj +++ b/src/Projections/Benchmark/Benchmark.csproj @@ -5,10 +5,6 @@ x64;x86 - - true - - diff --git a/src/Projections/Directory.Build.props b/src/Projections/Directory.Build.props index 4cf186e3d..d8488ba85 100644 --- a/src/Projections/Directory.Build.props +++ b/src/Projections/Directory.Build.props @@ -3,7 +3,11 @@ true - + + + true + + diff --git a/src/Projections/Test/Test.csproj b/src/Projections/Test/Test.csproj index f1943b757..ad43fb7d5 100644 --- a/src/Projections/Test/Test.csproj +++ b/src/Projections/Test/Test.csproj @@ -5,10 +5,6 @@ x64;x86 - - true - - diff --git a/src/Projections/TestHost.ProbeByClass/TestHost.ProbeByClass.csproj b/src/Projections/TestHost.ProbeByClass/TestHost.ProbeByClass.csproj index 5204fce19..16f85c34a 100644 --- a/src/Projections/TestHost.ProbeByClass/TestHost.ProbeByClass.csproj +++ b/src/Projections/TestHost.ProbeByClass/TestHost.ProbeByClass.csproj @@ -5,10 +5,6 @@ x64;x86 - - true - - diff --git a/src/Projections/WinUI/WinUI.csproj b/src/Projections/WinUI/WinUI.csproj index b5984b310..3228b7d65 100644 --- a/src/Projections/WinUI/WinUI.csproj +++ b/src/Projections/WinUI/WinUI.csproj @@ -5,10 +5,6 @@ x64;x86 - - true - - diff --git a/src/Projections/Windows/Windows.csproj b/src/Projections/Windows/Windows.csproj index 1e2fb5c3f..f0e9d5265 100644 --- a/src/Projections/Windows/Windows.csproj +++ b/src/Projections/Windows/Windows.csproj @@ -5,10 +5,6 @@ x64;x86 - - true - - diff --git a/src/Tests/AuthoringTest/AuthoringTest.csproj b/src/Tests/AuthoringTest/AuthoringTest.csproj index 5463316af..fb1fd1db2 100644 --- a/src/Tests/AuthoringTest/AuthoringTest.csproj +++ b/src/Tests/AuthoringTest/AuthoringTest.csproj @@ -7,7 +7,6 @@ - true diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest (Package)/AuthoringWinUITest (Package).wapproj b/src/Tests/AuthoringWinUITest/AuthoringWinUITest (Package)/AuthoringWinUITest (Package).wapproj index 116ca8e36..36bba7db4 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest (Package)/AuthoringWinUITest (Package).wapproj +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest (Package)/AuthoringWinUITest (Package).wapproj @@ -41,7 +41,6 @@ 10.0.17763.0 en-US false - $(MSBuildThisFileDirectory)build\ ..\AuthoringWinUITest\AuthoringWinUITest.vcxproj <_WinMDPlatform>$(Platform) <_WinMDPlatform Condition="'$(Platform)' == 'Win32'">x86 @@ -79,5 +78,4 @@ - \ No newline at end of file diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest (Package)/build/Microsoft.WinUI.AppX.targets b/src/Tests/AuthoringWinUITest/AuthoringWinUITest (Package)/build/Microsoft.WinUI.AppX.targets deleted file mode 100644 index b88f956f5..000000000 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest (Package)/build/Microsoft.WinUI.AppX.targets +++ /dev/null @@ -1,280 +0,0 @@ - - - - - - - - - - - - $(MSBuildThisFileDirectory) - - - $(WinUIClassRegistrationsDir.Substring(0,$(WinUIClassRegistrationsDir.IndexOf(';')))) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $(MSBuildWarningsAsMessages); - - - APPX1707; - - - $(MSBuildWarningsAsMessages); - - - MSB3268; - - - - - - true - - $(MSBuildWarningsAsMessages); - MSB3842; - MSB3843; - - - - - - - - - Windows - 10.0 - en-US - - - - - - <_MuxRuntimeIdentifier Condition="'$(Platform)' == 'Win32'">win10-x86 - <_MuxRuntimeIdentifier Condition="'$(Platform)' != 'Win32'">win10-$(Platform) - - - - $([MSBuild]::MakeRelative($(MSBuildThisFileDirectory)..\runtimes\$(_MuxRuntimeIdentifier)\native\, %(RootDir)%(Directory))) - - - - - - - - - $(OutDir)%(_FilteredNonWapProjProjectOutput.DestinationSubDirectory)%(Filename)%(Extension) - - - $(OutDir)%(_FilteredNonWapProjProjectOutput.DestinationSubDirectory)%(Filename)%(Extension) - - - - - - - - - %(WapProjPackageFile.DestinationSubDirectory)%(TargetPath) - - - %(UploadWapProjPackageFile.DestinationSubDirectory)%(TargetPath) - - - - - - - true - - - - - - - - - - - - - - true - - - - - - net5.0-windows$(TargetPlatformVersion);$(AssetTargetFallback) - - - - - - - - diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj index db6ad9941..1dc4578a4 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj @@ -1,9 +1,9 @@  - - - - + + + + true @@ -173,9 +173,10 @@ - - - + + + + @@ -184,12 +185,13 @@ - - - - - - - + + + + + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj.filters b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj.filters index 234faee9a..fd7f002af 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj.filters +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj.filters @@ -7,6 +7,7 @@ + diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/Directory.Build.targets b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/Directory.Build.targets index d0d6c4c99..dc80e1b3d 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/Directory.Build.targets +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/Directory.Build.targets @@ -4,13 +4,13 @@ CopyTestAssets;$(PrepareForRunDependsOn) - + diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/packages.config b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/packages.config index 4af55f681..c47ba540c 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/packages.config +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/packages.config @@ -1,9 +1,10 @@  - - - - + + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWinUITest/Directory.Build.targets b/src/Tests/AuthoringWinUITest/Directory.Build.targets index 5e495a946..7fe93ef50 100644 --- a/src/Tests/AuthoringWinUITest/Directory.Build.targets +++ b/src/Tests/AuthoringWinUITest/Directory.Build.targets @@ -1,5 +1,15 @@ + + CopyTestAssets;$(PrepareForRunDependsOn) + + + + + + diff --git a/src/Tests/DiagnosticTests/DiagnosticTests.csproj b/src/Tests/DiagnosticTests/DiagnosticTests.csproj index e7af4f914..dd4af04ad 100644 --- a/src/Tests/DiagnosticTests/DiagnosticTests.csproj +++ b/src/Tests/DiagnosticTests/DiagnosticTests.csproj @@ -3,7 +3,6 @@ net5.0-windows10.0.19041.0 false - true diff --git a/src/Tests/UnitTest/UnitTest.csproj b/src/Tests/UnitTest/UnitTest.csproj index a00ffb573..e63aeb190 100644 --- a/src/Tests/UnitTest/UnitTest.csproj +++ b/src/Tests/UnitTest/UnitTest.csproj @@ -9,7 +9,6 @@ true true false - true From 6f5ccdf26525e43579e87d6804dae89cce239a42 Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Thu, 10 Jun 2021 10:16:26 -0700 Subject: [PATCH 09/24] Clean-up. --- nuget/Microsoft.Windows.CsWinRT.targets | 42 +++++-------------- src/Perf/IIDOptimizer/GuidPatcher.cs | 31 ++------------ src/Perf/IIDOptimizer/Logger.cs | 10 ----- src/Perf/IIDOptimizer/Program.cs | 1 - src/Perf/IIDOptimizer/SignatureEmitter.cs | 17 +------- src/Perf/IIDOptimizer/SignatureGenerator.cs | 1 - src/Tests/AuthoringTest/AuthoringTest.csproj | 16 +++---- .../Directory.Build.targets | 6 +-- .../Directory.Build.targets | 10 ----- src/build.cmd | 1 - 10 files changed, 26 insertions(+), 109 deletions(-) diff --git a/nuget/Microsoft.Windows.CsWinRT.targets b/nuget/Microsoft.Windows.CsWinRT.targets index 8dfe84207..f9537d606 100644 --- a/nuget/Microsoft.Windows.CsWinRT.targets +++ b/nuget/Microsoft.Windows.CsWinRT.targets @@ -119,42 +119,18 @@ $(CsWinRTFilters) - - - - - - - - - - - - - - - - - $(CsWinRTAuthoringInputs) @(CsWinRTInputs->'"%(FullPath)"', ' ') @(CsWinRTAuthoringWinMDs->'"%(FullPath)"', ' ') - - - - - - - - - + - - + BeforeTargets="Link"> + $(CsWinRTPath)build\tools\GuidPatch\ $(CsWinRTPath)lib\net5.0\ + @(BuiltProjectOutputGroupKeyOutput->'%(Identity)') + $([System.IO.Directory]::GetParent($(CsWinRTIIDOptimizerInput))) @@ -166,11 +142,13 @@ $(CsWinRTFilters) + - - + AfterTargets="CsWinRTInvokeGuidPatcher" + BeforeTargets="Link"> + + diff --git a/src/Perf/IIDOptimizer/GuidPatcher.cs b/src/Perf/IIDOptimizer/GuidPatcher.cs index 93d0bc980..38f7529e5 100644 --- a/src/Perf/IIDOptimizer/GuidPatcher.cs +++ b/src/Perf/IIDOptimizer/GuidPatcher.cs @@ -57,6 +57,7 @@ public GuidPatcher(string assemblyPath, IAssemblyResolver assemblyResolver, Asse ApplyWindowsRuntimeProjections = false }); + winRTRuntimeAssembly = winRTRuntime; guidImplementationDetailsType = new TypeDefinition(null, "", TypeAttributes.AutoClass | TypeAttributes.Sealed, assembly.MainModule.TypeSystem.Object); @@ -125,7 +126,6 @@ public int ProcessAssembly() return 0; } - Logger.Log($"Processing assembly: {assembly}."); int numPatches = 0; var methods = from module in assembly.Modules from type in module.Types @@ -157,11 +157,6 @@ enum State private bool PatchNonGenericTypeIID(MethodBody body, int startILIndex, TypeReference type, int numberOfInstructionsToOverwrite) { - /* - Logger.Log($"PatchNonGenericTypeIID"); - Logger.Log($"\tbody.Method = {body.Method}."); - Logger.Log($"\ttype = {type}."); - */ if (numberOfInstructionsToOverwrite < 2) { return false; @@ -188,11 +183,6 @@ private bool PatchNonGenericTypeIID(MethodBody body, int startILIndex, TypeRefer private bool PatchGenericTypeIID(MethodBody body, int startILIndex, TypeReference type, int numberOfInstructionsToOverwrite) { - /* - Logger.Log($"PatchGenericTypeIID:"); - Logger.Log($"\tbody.Method = {body.Method}."); - Logger.Log($"\ttype = {type}."); - */ SignaturePart rootSignaturePart = signatureGenerator.GetSignatureParts(type); var guidDataMethod = new MethodDefinition($"{type.FullName}", MethodAttributes.Assembly | MethodAttributes.Static, readOnlySpanOfByte); @@ -221,11 +211,6 @@ private bool PatchGenericTypeIID(MethodBody body, int startILIndex, TypeReferenc private void ReplaceWithCallToGuidDataGetter(MethodBody body, int startILIndex, int numberOfInstructionsToOverwrite, MethodReference guidDataMethod) { - /* - Logger.Log($"ReplaceWithCallToGuidDataGetter:"); - Logger.Log($"\tMethodBody = {body}."); - Logger.Log($"\tguidDataMethod = {guidDataMethod}."); - */ var il = body.GetILProcessor(); il.Replace(startILIndex, Instruction.Create(OpCodes.Call, guidDataMethod)); il.Replace(startILIndex + 1, Instruction.Create(OpCodes.Newobj, guidCtor)); @@ -237,13 +222,10 @@ private void ReplaceWithCallToGuidDataGetter(MethodBody body, int startILIndex, private void VisitSignature(SignaturePart rootSignaturePart, SignatureEmitter emitter) { - Logger.Log("VisitSignature"); - Logger.Log($"emitter: {emitter}"); switch (rootSignaturePart) { case BasicSignaturePart basic: { - Logger.TLog("(1)"); emitter.PushString(basic.Type switch { SignatureType.@string => "string", @@ -254,7 +236,6 @@ private void VisitSignature(SignaturePart rootSignaturePart, SignatureEmitter em break; case SignatureWithChildren group: { - Logger.TLog("(2)"); emitter.PushString($"{group.GroupingName}("); emitter.PushString(group.ThisEntitySignature); foreach (var item in group.ChildrenSignatures) @@ -267,29 +248,23 @@ private void VisitSignature(SignaturePart rootSignaturePart, SignatureEmitter em break; case GuidSignature guid: { - Logger.TLog("(3)"); emitter.PushString(guid.IID.ToString("B")); } break; case NonGenericDelegateSignature del: { - /// here! doesnt get hit - // Logger.TLog($"(4) NonGenericDelegateSignature = {del}"); - Logger.TLog("(4)"); + /// TODO test this path emitter.PushString($"delegate({del.DelegateIID:B}"); } break; case UninstantiatedGeneric gen: { - Logger.TLog("(5)"); emitter.PushGenericParameter(gen.OriginalGenericParameter); } break; case CustomSignatureMethod custom: { - // Logger.TLog($"(6) CustomSignatureMethod = {custom}"); - /// doesnt get hit - Logger.TLog("(6)"); + /// TODO test this path emitter.PushCustomSignature(custom.Method); } break; diff --git a/src/Perf/IIDOptimizer/Logger.cs b/src/Perf/IIDOptimizer/Logger.cs index e147b4d07..0f8dabee1 100644 --- a/src/Perf/IIDOptimizer/Logger.cs +++ b/src/Perf/IIDOptimizer/Logger.cs @@ -4,11 +4,6 @@ namespace GuidPatch { class Logger { - public Logger(string parentDir) - { - string logFile = Path.Combine(parentDir, "log.txt"); - fileLogger = File.CreateText(logFile); - } public Logger(string parentDir, string fileName) { string logFile = Path.Combine(parentDir, fileName); @@ -20,11 +15,6 @@ public void Log(string text) fileLogger?.WriteLine(text); } - public void TLog(string text) - { - fileLogger?.WriteLine("\t" + text); - } - public void Close() { fileLogger?.Close(); diff --git a/src/Perf/IIDOptimizer/Program.cs b/src/Perf/IIDOptimizer/Program.cs index 635f94354..fc1e18e2d 100644 --- a/src/Perf/IIDOptimizer/Program.cs +++ b/src/Perf/IIDOptimizer/Program.cs @@ -30,7 +30,6 @@ static void Main(string[] args) resolver, winRTRuntimeAssembly); - // moved to GuidPAtcher constructor. Directory.CreateDirectory(guidPatcher.OptimizerDir); int numPatches = guidPatcher.ProcessAssembly(); guidPatcher.SaveAssembly(guidPatcher.OptimizerDir); Console.WriteLine($"{numPatches} IID calculations/fetches patched"); diff --git a/src/Perf/IIDOptimizer/SignatureEmitter.cs b/src/Perf/IIDOptimizer/SignatureEmitter.cs index 0cb3a582f..a8b482ba6 100644 --- a/src/Perf/IIDOptimizer/SignatureEmitter.cs +++ b/src/Perf/IIDOptimizer/SignatureEmitter.cs @@ -46,11 +46,9 @@ public SignatureEmitter(TypeReference describedType, MethodDefinition guidDataGe /* * Initialize the logger with the OptimizerDir property */ - Logger = logger; // new Logger(OptimizerDir, "emitter.log.txt"); + Logger = logger; } - public void CloseLogger() { Logger.Close(); } - public void PushString(string str) { if (currentStringBuilder is null) @@ -152,11 +150,6 @@ private void GenerateGuidFromSimpleSignature(StringStep stringStep, TypeDefiniti private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementationDetailsType, TypeReference readOnlySpanOfByte, MethodReference readOnlySpanOfBytePtrCtor, TypeDefinition guidGeneratorType) { - /* - Logger.Log("GenerateGuidFactoryFromComplexSignature"); - Logger.TLog($"implementationDetailsType : {implementationDetailsType}"); - Logger.TLog($"guidGeneratorType : {guidGeneratorType}"); - */ var module = implementationDetailsType.Module; var readOnlySpanOfByteArrayCtor = module.ImportReference( @@ -236,8 +229,6 @@ private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementati { case StringStep(string str): { - // Logger.Log("(1) StringStep"); - // Logger.TLog($"str = {str}"); byte[] segmentBytes = Encoding.UTF8.GetBytes(str); var staticDataField = new FieldDefinition($"", FieldAttributes.Private | FieldAttributes.InitOnly | FieldAttributes.Static | FieldAttributes.HasFieldRVA, CecilExtensions.GetOrCreateDataBlockType(implementationDetailsType, segmentBytes.Length)) { @@ -259,8 +250,6 @@ private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementati break; case RuntimeGenericSignatureStep(_, GenericParameter localTypeParameter): { - // Logger.Log("(2) RuntimeGenericSignatureStep"); - // Logger.TLog($"localTypeParameter = {localTypeParameter}"); // byte[] bytes = Encoding.UTF8.GetBytes(GetSignature(typeof(localTypeParameter))) il.Emit(OpCodes.Call, utf8EncodingGetter); il.Emit(OpCodes.Ldtoken, localTypeParameter); @@ -280,9 +269,7 @@ private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementati break; case RuntimeCustomSignatureStep(MethodReference customSignatureMethod): { - /// not called - // Logger.Log("(3) RuntimeCustomSignatureStep"); - // Logger.TLog($"customSignatureMethod = {customSignatureMethod}"); + /// TODO test this pat h // byte[] bytes = Encoding.UTF8.GetBytes(customSignatureMethod()) il.Emit(OpCodes.Call, utf8EncodingGetter); il.Emit(OpCodes.Call, customSignatureMethod); diff --git a/src/Perf/IIDOptimizer/SignatureGenerator.cs b/src/Perf/IIDOptimizer/SignatureGenerator.cs index f570fff39..0cbb8a160 100644 --- a/src/Perf/IIDOptimizer/SignatureGenerator.cs +++ b/src/Perf/IIDOptimizer/SignatureGenerator.cs @@ -58,7 +58,6 @@ sealed class SignatureGenerator private readonly TypeDefinition guidAttributeType; private readonly AssemblyDefinition winRTRuntimeAssembly; - /* Constructor: paramterized by the projection, the guid type (?), and the winrt.runtime (could use winrt.runtime.dll version 1.2.1 or 1.2.5 */ public SignatureGenerator(AssemblyDefinition assembly, TypeDefinition guidAttributeType, AssemblyDefinition runtimeAssembly) { this.assembly = assembly; diff --git a/src/Tests/AuthoringTest/AuthoringTest.csproj b/src/Tests/AuthoringTest/AuthoringTest.csproj index fb1fd1db2..691b01690 100644 --- a/src/Tests/AuthoringTest/AuthoringTest.csproj +++ b/src/Tests/AuthoringTest/AuthoringTest.csproj @@ -5,18 +5,18 @@ x64;x86 true - + true - - - - - - - + + + + + + + diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/Directory.Build.targets b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/Directory.Build.targets index dc80e1b3d..2703424c4 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/Directory.Build.targets +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/Directory.Build.targets @@ -1,16 +1,16 @@ - + CopyTestAssets;$(PrepareForRunDependsOn) - - --> + diff --git a/src/Tests/AuthoringWinUITest/Directory.Build.targets b/src/Tests/AuthoringWinUITest/Directory.Build.targets index 7fe93ef50..5e495a946 100644 --- a/src/Tests/AuthoringWinUITest/Directory.Build.targets +++ b/src/Tests/AuthoringWinUITest/Directory.Build.targets @@ -1,15 +1,5 @@ - - CopyTestAssets;$(PrepareForRunDependsOn) - - - - - - diff --git a/src/build.cmd b/src/build.cmd index 27004f777..84b899e1e 100644 --- a/src/build.cmd +++ b/src/build.cmd @@ -131,7 +131,6 @@ if ErrorLevel 1 ( exit /b !ErrorLevel! ) if "%cswinrt_build_only%"=="true" goto :eof -if "%cswinrt_buildpack%"=="true" goto :package :test :unittest From 8ada065bcc3e7428363f76d019c61beb1e12ad22 Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Fri, 11 Jun 2021 15:12:57 -0700 Subject: [PATCH 10/24] Add tests for iidoptimizer --- src/Tests/TestComponentCSharp/Class.cpp | 15 +++++++++++++++ src/Tests/TestComponentCSharp/Class.h | 4 ++++ .../TestComponentCSharp/TestComponentCSharp.idl | 4 ++++ 3 files changed, 23 insertions(+) diff --git a/src/Tests/TestComponentCSharp/Class.cpp b/src/Tests/TestComponentCSharp/Class.cpp index c5f355bc3..4eea4084d 100644 --- a/src/Tests/TestComponentCSharp/Class.cpp +++ b/src/Tests/TestComponentCSharp/Class.cpp @@ -946,6 +946,21 @@ namespace winrt::TestComponentCSharp::implementation { return winrt::single_threaded_vector_view(std::vector{ *this, *this, *this }); } + + // Test IIDOptimizer + IVectorView Class::GetEventArgsVector() + { + auto mock = make(L"name"); + DataErrorsChangedEventArgs args(detach_abi(mock), take_ownership_from_abi_t()); + return winrt::single_threaded_vector_view(std::vector{ args }); + } + + // Test IIDOptimizer + IVectorView Class::GetNonGenericDelegateVector() + { + TestComponentCSharp::ProvideUri handler = [] { return Windows::Foundation::Uri(L"http://microsoft.com"); }; + return winrt::single_threaded_vector_view(std::vector{ handler }); + } void Class::CompleteAsync() { diff --git a/src/Tests/TestComponentCSharp/Class.h b/src/Tests/TestComponentCSharp/Class.h index 9d36e88a6..ed9bc6c5d 100644 --- a/src/Tests/TestComponentCSharp/Class.h +++ b/src/Tests/TestComponentCSharp/Class.h @@ -266,6 +266,10 @@ namespace winrt::TestComponentCSharp::implementation Windows::Foundation::Collections::IVectorView GetObjectVector(); Windows::Foundation::Collections::IVectorView GetInterfaceVector(); Windows::Foundation::Collections::IVectorView GetClassVector() noexcept; + + // Test IIDOptimizer + Windows::Foundation::Collections::IVectorView GetEventArgsVector(); + Windows::Foundation::Collections::IVectorView GetNonGenericDelegateVector(); Windows::Foundation::Collections::IIterable GetIntIterable(); void SetIntIterable(Windows::Foundation::Collections::IIterable const& value); diff --git a/src/Tests/TestComponentCSharp/TestComponentCSharp.idl b/src/Tests/TestComponentCSharp/TestComponentCSharp.idl index c98330e28..0bb5bf897 100644 --- a/src/Tests/TestComponentCSharp/TestComponentCSharp.idl +++ b/src/Tests/TestComponentCSharp/TestComponentCSharp.idl @@ -298,6 +298,10 @@ namespace TestComponentCSharp Windows.Foundation.Collections.IVectorView GetInterfaceVector(); [noexcept] Windows.Foundation.Collections.IVectorView GetClassVector(); + // Test IIDOptimizer + Windows.Foundation.Collections.IVectorView GetEventArgsVector(); + Windows.Foundation.Collections.IVectorView GetNonGenericDelegateVector(); + Windows.Foundation.Collections.IIterable GetIntIterable(); void SetIntIterable(Windows.Foundation.Collections.IIterable value); From 4061d6b29912cdbde49e263ebb492fbfd17d3d50 Mon Sep 17 00:00:00 2001 From: Manodasan Wignarajah Date: Sun, 13 Jun 2021 15:57:27 -0700 Subject: [PATCH 11/24] Fix issue causing IID optimizer to not run and add notice file for library dependencies we distribute --- nuget/Microsoft.Windows.CsWinRT.nuspec | 1 + nuget/Microsoft.Windows.CsWinRT.targets | 2 +- nuget/NOTICE.txt | 42 +++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 nuget/NOTICE.txt diff --git a/nuget/Microsoft.Windows.CsWinRT.nuspec b/nuget/Microsoft.Windows.CsWinRT.nuspec index cb4e981db..01060e47c 100644 --- a/nuget/Microsoft.Windows.CsWinRT.nuspec +++ b/nuget/Microsoft.Windows.CsWinRT.nuspec @@ -19,6 +19,7 @@ + diff --git a/nuget/Microsoft.Windows.CsWinRT.targets b/nuget/Microsoft.Windows.CsWinRT.targets index b50a52284..9aceef3f7 100644 --- a/nuget/Microsoft.Windows.CsWinRT.targets +++ b/nuget/Microsoft.Windows.CsWinRT.targets @@ -132,7 +132,7 @@ $(CsWinRTIncludeWinRTInterop) BeforeTargets="Link"> - $(CsWinRTPath)build\tools\GuidPatch\ + $(CsWinRTPath)build\tools\IIDOptimizer\ $(CsWinRTPath)lib\net5.0\ @(BuiltProjectOutputGroupKeyOutput->'%(Identity)') diff --git a/nuget/NOTICE.txt b/nuget/NOTICE.txt new file mode 100644 index 000000000..8e570fdba --- /dev/null +++ b/nuget/NOTICE.txt @@ -0,0 +1,42 @@ +NOTICES AND INFORMATION +Do Not Translate or Localize + +This software incorporates material from third parties. +Microsoft makes certain open source code available at https://3rdpartysource.microsoft.com, +or you may send a check or money order for US $5.00, including the product name, +the open source component name, platform, and version number, to: + +Source Code Compliance Team +Microsoft Corporation +One Microsoft Way +Redmond, WA 98052 +USA + +Notwithstanding any other terms, you may reverse engineer this software to the extent +required to debug changes to any libraries licensed under the GNU Lesser General Public License. + +--------------------------------------------------------- + +Mono.Cecil 0.11.3 - MIT + +Copyright (c) 2008 - 2015 Jb Evain +Copyright (c) 2008 - 2011 Novell, Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. From 455f11bd77bb91621598c901a8c0a94664691cd6 Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Mon, 14 Jun 2021 13:40:37 -0700 Subject: [PATCH 12/24] Clean up. --- src/Perf/IIDOptimizer/Program.cs | 8 +++-- src/Projections/Directory.Build.props | 2 +- src/Projections/Test/Test.csproj | 4 +-- src/Tests/TestComponentCSharp/Class.h | 2 +- src/WinRT.Runtime/Directory.Build.targets | 37 +++++++++++++++++++++++ 5 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 src/WinRT.Runtime/Directory.Build.targets diff --git a/src/Perf/IIDOptimizer/Program.cs b/src/Perf/IIDOptimizer/Program.cs index fc1e18e2d..67ca4e6e6 100644 --- a/src/Perf/IIDOptimizer/Program.cs +++ b/src/Perf/IIDOptimizer/Program.cs @@ -6,11 +6,12 @@ namespace GuidPatch { class Program { - static void Main(string[] args) + static int Main(string[] args) { if (args.Length != 2) { Console.WriteLine($"Expected to be given two arguments. Given {args.Length}"); + return -1; } else { @@ -33,11 +34,12 @@ static void Main(string[] args) int numPatches = guidPatcher.ProcessAssembly(); guidPatcher.SaveAssembly(guidPatcher.OptimizerDir); Console.WriteLine($"{numPatches} IID calculations/fetches patched"); + return 0; } catch (AssemblyResolutionException) { - Console.WriteLine("Failed to resolve WinRT.Runtime, shutting down."); - return; + Console.WriteLine("Failed to resolve an assembly, shutting down."); + return -2; } } } diff --git a/src/Projections/Directory.Build.props b/src/Projections/Directory.Build.props index d8488ba85..2a4d3b6cf 100644 --- a/src/Projections/Directory.Build.props +++ b/src/Projections/Directory.Build.props @@ -4,7 +4,7 @@ true - + true diff --git a/src/Projections/Test/Test.csproj b/src/Projections/Test/Test.csproj index 867f91ae4..2dd8d8a4e 100644 --- a/src/Projections/Test/Test.csproj +++ b/src/Projections/Test/Test.csproj @@ -8,8 +8,8 @@ - - + + diff --git a/src/Tests/TestComponentCSharp/Class.h b/src/Tests/TestComponentCSharp/Class.h index ed9bc6c5d..7f1d35842 100644 --- a/src/Tests/TestComponentCSharp/Class.h +++ b/src/Tests/TestComponentCSharp/Class.h @@ -267,7 +267,7 @@ namespace winrt::TestComponentCSharp::implementation Windows::Foundation::Collections::IVectorView GetInterfaceVector(); Windows::Foundation::Collections::IVectorView GetClassVector() noexcept; - // Test IIDOptimizer + // Test IIDOptimizer -- testing the windows projection covers most code paths, and these two types exercise the rest. Windows::Foundation::Collections::IVectorView GetEventArgsVector(); Windows::Foundation::Collections::IVectorView GetNonGenericDelegateVector(); diff --git a/src/WinRT.Runtime/Directory.Build.targets b/src/WinRT.Runtime/Directory.Build.targets new file mode 100644 index 000000000..13d5edf78 --- /dev/null +++ b/src/WinRT.Runtime/Directory.Build.targets @@ -0,0 +1,37 @@ + + + + + + C:\Users\jlarkin\.nuget\packages\microsoft.windows.cswinrt\1.2.6\lib\net5.0 + $(CsWinRTPath)build\tools\GuidPatch\ + @(BuiltProjectOutputGroupKeyOutput->'%(Identity)') + $([System.IO.Directory]::GetParent($(CsWinRTIIDOptimizerInput))) + + + + + + + + + + + + + + + + + + + + + + + From 19f87681e8e10e6d933a88e1121a340d3d567f50 Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Tue, 22 Jun 2021 14:42:55 -0700 Subject: [PATCH 13/24] Update to pass parameters; remove unused class; pass logger (for now) --- .../IIDOptimizer/FolderAssemblyResolver.cs | 30 ------------------- src/Perf/IIDOptimizer/GuidPatcher.cs | 25 +++++++++++----- src/Perf/IIDOptimizer/SignatureGenerator.cs | 3 +- src/get_testwinrt.cmd | 2 +- 4 files changed, 19 insertions(+), 41 deletions(-) delete mode 100644 src/Perf/IIDOptimizer/FolderAssemblyResolver.cs diff --git a/src/Perf/IIDOptimizer/FolderAssemblyResolver.cs b/src/Perf/IIDOptimizer/FolderAssemblyResolver.cs deleted file mode 100644 index 719862297..000000000 --- a/src/Perf/IIDOptimizer/FolderAssemblyResolver.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Mono.Cecil; -using System; -using System.IO; -using System.Linq; - -namespace GuidPatch -{ - class FolderAssemblyResolver : DefaultAssemblyResolver - { - public FolderAssemblyResolver(params DirectoryInfo[] directories) - { - foreach (var file in directories.SelectMany(d => d.EnumerateFiles("*.dll"))) - { - try - { - var definition = AssemblyDefinition.ReadAssembly(file.FullName, new ReaderParameters(ReadingMode.Deferred) - { - InMemory = true, - ReadWrite = false, - AssemblyResolver = this - }); - RegisterAssembly(definition); - } - catch (Exception) - { - } - } - } - } -} diff --git a/src/Perf/IIDOptimizer/GuidPatcher.cs b/src/Perf/IIDOptimizer/GuidPatcher.cs index 38f7529e5..cce832ca4 100644 --- a/src/Perf/IIDOptimizer/GuidPatcher.cs +++ b/src/Perf/IIDOptimizer/GuidPatcher.cs @@ -44,18 +44,21 @@ public GuidPatcher(string assemblyPath, IAssemblyResolver assemblyResolver, Asse */ Logger = new Logger(OptimizerDir, "log.txt"); - /* - * Initialize readonly fields - */ - assembly = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters(ReadingMode.Deferred) + var readerParameters = new ReaderParameters(ReadingMode.Deferred) { ReadWrite = true, InMemory = true, AssemblyResolver = assemblyResolver, ThrowIfSymbolsAreNotMatching = false, SymbolReaderProvider = new DefaultSymbolReaderProvider(false), - ApplyWindowsRuntimeProjections = false - }); + ApplyWindowsRuntimeProjections = false, + ReadSymbols = true + }; + + /* + * Initialize readonly fields + */ + assembly = AssemblyDefinition.ReadAssembly(assemblyPath, readerParameters); winRTRuntimeAssembly = winRTRuntime; @@ -116,7 +119,7 @@ public GuidPatcher(string assemblyPath, IAssemblyResolver assemblyResolver, Asse getHelperTypeMethod = typeExtensionsType.Methods.First(m => m.Name == "GetHelperType"); } - signatureGenerator = new SignatureGenerator(assembly, guidAttributeType!, winRTRuntimeAssembly); + signatureGenerator = new SignatureGenerator(assembly, guidAttributeType!, winRTRuntimeAssembly, Logger); } public int ProcessAssembly() @@ -144,7 +147,13 @@ where method.HasBody public void SaveAssembly(string targetDirectory) { - assembly.Write($"{targetDirectory}{Path.DirectorySeparatorChar}{assembly.Name.Name}.dll"); + var writerParameters = new WriterParameters + { + // SymbolWriterProvider = new DefaultSymbolWriterProvider(), + WriteSymbols = true + }; + + assembly.Write($"{targetDirectory}{Path.DirectorySeparatorChar}{assembly.Name.Name}.dll", writerParameters); } enum State diff --git a/src/Perf/IIDOptimizer/SignatureGenerator.cs b/src/Perf/IIDOptimizer/SignatureGenerator.cs index 0cbb8a160..07d0958b0 100644 --- a/src/Perf/IIDOptimizer/SignatureGenerator.cs +++ b/src/Perf/IIDOptimizer/SignatureGenerator.cs @@ -58,7 +58,7 @@ sealed class SignatureGenerator private readonly TypeDefinition guidAttributeType; private readonly AssemblyDefinition winRTRuntimeAssembly; - public SignatureGenerator(AssemblyDefinition assembly, TypeDefinition guidAttributeType, AssemblyDefinition runtimeAssembly) + public SignatureGenerator(AssemblyDefinition assembly, TypeDefinition guidAttributeType, AssemblyDefinition runtimeAssembly, Logger logger) { this.assembly = assembly; this.guidAttributeType = guidAttributeType; @@ -178,7 +178,6 @@ public SignaturePart GetSignatureParts(TypeReference type) { return new NonGenericDelegateSignature(guidAttributeValue.Value); } - return new GuidSignature(guidAttributeValue.Value); } diff --git a/src/get_testwinrt.cmd b/src/get_testwinrt.cmd index ba2838c0c..9188b2f86 100644 --- a/src/get_testwinrt.cmd +++ b/src/get_testwinrt.cmd @@ -14,7 +14,7 @@ git checkout -f master if ErrorLevel 1 popd & exit /b !ErrorLevel! git fetch -f if ErrorLevel 1 popd & exit /b !ErrorLevel! -git reset -q --hard 45c6a357c0293d202a1c090e18d24ce42833fd23 +git reset -q --hard e7682136641caf9713268761ec8188ca452e85f9 if ErrorLevel 1 popd & exit /b !ErrorLevel! echo Restoring Nuget %this_dir%.nuget\nuget.exe restore From 7d727143c7b6f28d4e01f032f7d0378dd76fae79 Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Thu, 8 Jul 2021 16:00:30 -0700 Subject: [PATCH 14/24] Update patcher exe, now resolving reference assemblies. --- nuget/Microsoft.Windows.CsWinRT.targets | 65 ++++++++--- src/Perf/IIDOptimizer/GuidPatcher.cs | 13 +-- src/Perf/IIDOptimizer/IIDOptimizer.csproj | 8 +- src/Perf/IIDOptimizer/Program.cs | 104 ++++++++++++------ .../Properties/launchSettings.json | 8 ++ .../IIDOptimizer/ReferenceAssemblyResolver.cs | 21 ++++ src/Perf/IIDOptimizer/SignatureEmitter.cs | 20 ++-- 7 files changed, 175 insertions(+), 64 deletions(-) create mode 100644 src/Perf/IIDOptimizer/Properties/launchSettings.json create mode 100644 src/Perf/IIDOptimizer/ReferenceAssemblyResolver.cs diff --git a/nuget/Microsoft.Windows.CsWinRT.targets b/nuget/Microsoft.Windows.CsWinRT.targets index 9aceef3f7..5c880ebff 100644 --- a/nuget/Microsoft.Windows.CsWinRT.targets +++ b/nuget/Microsoft.Windows.CsWinRT.targets @@ -68,7 +68,10 @@ Copyright (C) Microsoft Corporation. All rights reserved. $(CsWinRTGeneratedFilesDir)cswinrt.rsp - "$(CsWinRTExe)" %40"$(CsWinRTResponseFile)" + + "$(CsWinRTExe)" %40"$(CsWinRTResponseFile)" $(WindowsSDKVersion.TrimEnd('\')) $(TargetPlatformVersion) -input $(CsWinRTWindowsMetadata) @@ -125,30 +128,57 @@ $(CsWinRTIncludeWinRTInterop) - - + + + - + $(CsWinRTPath)build\tools\IIDOptimizer\ + + @(BuiltProjectOutputGroupKeyOutput->'%(Identity)') + $(CsWinRTPath)lib\net5.0\ - - @(BuiltProjectOutputGroupKeyOutput->'%(Identity)') - - $([System.IO.Directory]::GetParent($(CsWinRTIIDOptimizerInput))) + + @(ReferencePathWithRefAssemblies->'--refs %(Identity)', ' ') + + +--target +$(CsWinRTIIDOptimizerTargetAssembly) +--runtime +$(CsWinRTIIDOptimizerRuntimePath) +$(GuidPatchTargetAssemblyReferences) + - + + + + obj\IIDOptimizer\cswinrt_iidoptimizer.rsp + "$(CsWinRTIIDOptimizerPath)IIDOptimizer.exe" %40"$(CsWinRTIIDOptimizerResponseFile)" + + + + + + + + + - + + + + $([System.IO.Directory]::GetParent($(CsWinRTIIDOptimizerTargetAssembly))) + + diff --git a/src/Perf/IIDOptimizer/GuidPatcher.cs b/src/Perf/IIDOptimizer/GuidPatcher.cs index cce832ca4..48d4756f0 100644 --- a/src/Perf/IIDOptimizer/GuidPatcher.cs +++ b/src/Perf/IIDOptimizer/GuidPatcher.cs @@ -1,4 +1,5 @@ using Mono.Cecil; +using Mono.Cecil.Pdb; using Mono.Cecil.Cil; using System; using System.Collections.Generic; @@ -42,7 +43,7 @@ public GuidPatcher(string assemblyPath, IAssemblyResolver assemblyResolver, Asse /* * Initialize the logger with the OptimizerDir property */ - Logger = new Logger(OptimizerDir, "log.txt"); + Logger = new Logger(OptimizerDir, "log_iidoptimizer.txt"); var readerParameters = new ReaderParameters(ReadingMode.Deferred) { @@ -149,7 +150,6 @@ public void SaveAssembly(string targetDirectory) { var writerParameters = new WriterParameters { - // SymbolWriterProvider = new DefaultSymbolWriterProvider(), WriteSymbols = true }; @@ -198,9 +198,9 @@ private bool PatchGenericTypeIID(MethodBody body, int startILIndex, TypeReferenc guidImplementationDetailsType.Methods.Add(guidDataMethod); - var emitter = new SignatureEmitter(type, guidDataMethod, Logger); + var emitter = new SignatureEmitter(type, guidDataMethod, Logger); VisitSignature(rootSignaturePart, emitter); - + emitter.EmitGuidGetter(guidDataBlockType, guidImplementationDetailsType, readOnlySpanOfByte, readOnlySpanOfByteCtor, guidGeneratorType!); MethodReference guidDataMethodReference = guidDataMethod; @@ -235,7 +235,7 @@ private void VisitSignature(SignaturePart rootSignaturePart, SignatureEmitter em { case BasicSignaturePart basic: { - emitter.PushString(basic.Type switch + emitter.PushString(basic.Type switch { SignatureType.@string => "string", SignatureType.iinspectable => "cinterface(IInspectable)", @@ -262,7 +262,6 @@ private void VisitSignature(SignaturePart rootSignaturePart, SignatureEmitter em break; case NonGenericDelegateSignature del: { - /// TODO test this path emitter.PushString($"delegate({del.DelegateIID:B}"); } break; @@ -273,7 +272,6 @@ private void VisitSignature(SignaturePart rootSignaturePart, SignatureEmitter em break; case CustomSignatureMethod custom: { - /// TODO test this path emitter.PushCustomSignature(custom.Method); } break; @@ -374,6 +372,7 @@ private int ProcessMethodBody(MethodBody body, MethodDefinition getTypeFromHandl } catch (Exception ex) { + Logger.Log($"Exception thrown during patching {body.Method.FullName}: {ex}"); Debug.WriteLine($"Exception thrown during patching {body.Method.FullName}: {ex}"); } } diff --git a/src/Perf/IIDOptimizer/IIDOptimizer.csproj b/src/Perf/IIDOptimizer/IIDOptimizer.csproj index bc07a8798..5f4eecbe3 100644 --- a/src/Perf/IIDOptimizer/IIDOptimizer.csproj +++ b/src/Perf/IIDOptimizer/IIDOptimizer.csproj @@ -6,8 +6,14 @@ enable + + + https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-libraries/nuget/v3/index.json + + - + + diff --git a/src/Perf/IIDOptimizer/Program.cs b/src/Perf/IIDOptimizer/Program.cs index 67ca4e6e6..a5ef49e20 100644 --- a/src/Perf/IIDOptimizer/Program.cs +++ b/src/Perf/IIDOptimizer/Program.cs @@ -1,46 +1,86 @@ using Mono.Cecil; using System; using System.IO; +using System.CommandLine; +using System.CommandLine.Invocation; +using System.Threading.Tasks; +using System.Collections.Generic; namespace GuidPatch { class Program { - static int Main(string[] args) + static readonly Option _targetAssembly = + new Option + ( + name: "--targetAssembly", + description: "The assembly to perform GUID optimizations on.", + argumentType: typeof(string), + arity: ArgumentArity.ExactlyOne + ); + + static readonly Option _runtimePath = + new Option + ( + name: "--runtimePath", + description: "The path to the folder used to resolve WinRT.Runtime.dll assembly.", + argumentType: typeof(string), + arity: ArgumentArity.ExactlyOne + ); + + static readonly Option _references = + new Option + ( + name: "--references", + description: "Reference assemblies used when compiling the target assembly.", + argumentType: typeof(FileInfo[]), + arity: ArgumentArity.ZeroOrMore + ); + + + static async Task Main(string[] args) { - if (args.Length != 2) + var rootCommand = new RootCommand { }; + // friendlier option names + _targetAssembly.AddAlias("--target"); + _runtimePath.AddAlias("--runtime"); + _references.AddAlias("--refs"); + + rootCommand.AddOption(_targetAssembly); + rootCommand.AddOption(_runtimePath); + rootCommand.AddOption(_references); + + rootCommand.Handler = CommandHandler.Create>(GuidPatch); + await rootCommand.InvokeAsync(args); + } + + private static int GuidPatch(string targetAssembly, string runtimePath, IEnumerable references) + { + // pass targetAssembly here and update ReferenceAssemblyResolver to use it when resolving ==> can patch WinRT.Runtime itself + var resolver = new ReferenceAssemblyResolver(references); + try { - Console.WriteLine($"Expected to be given two arguments. Given {args.Length}"); - return -1; + AssemblyDefinition winRTRuntimeAssembly = resolver.Resolve(new AssemblyNameReference("WinRT.Runtime", default)); + + Directory.CreateDirectory("obj\\IIDOptimizer"); + + var guidPatcher = new GuidPatcher( + targetAssembly, + resolver, + winRTRuntimeAssembly); + + int numPatches = guidPatcher.ProcessAssembly(); + + guidPatcher.SaveAssembly(guidPatcher.OptimizerDir); + + Console.WriteLine($"{numPatches} IID calculations/fetches patched"); + return 0; } - else - { - /* The first argument given is the .dll to patch - The second argument is the folder to look for winrt.runtime in */ - var resolver = new DefaultAssemblyResolver(); - - try - { - resolver.AddSearchDirectory(args[1]); - AssemblyDefinition winRTRuntimeAssembly = resolver.Resolve(new AssemblyNameReference("WinRT.Runtime", default)); - - Directory.CreateDirectory("obj\\IIDOptimizer"); - - var guidPatcher = new GuidPatcher( - args[0], - resolver, - winRTRuntimeAssembly); - - int numPatches = guidPatcher.ProcessAssembly(); - guidPatcher.SaveAssembly(guidPatcher.OptimizerDir); - Console.WriteLine($"{numPatches} IID calculations/fetches patched"); - return 0; - } - catch (AssemblyResolutionException) - { - Console.WriteLine("Failed to resolve an assembly, shutting down."); - return -2; - } + catch (AssemblyResolutionException e) + { + Console.WriteLine("Failed to resolve an assembly, shutting down."); + Console.WriteLine($"\tAssembly : {e.AssemblyReference.Name}"); + return -1; } } } diff --git a/src/Perf/IIDOptimizer/Properties/launchSettings.json b/src/Perf/IIDOptimizer/Properties/launchSettings.json new file mode 100644 index 000000000..f61327d06 --- /dev/null +++ b/src/Perf/IIDOptimizer/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "IIDOptimizer": { + "commandName": "Project", + "nativeDebugging": true + } + } +} \ No newline at end of file diff --git a/src/Perf/IIDOptimizer/ReferenceAssemblyResolver.cs b/src/Perf/IIDOptimizer/ReferenceAssemblyResolver.cs new file mode 100644 index 000000000..03b0ee82c --- /dev/null +++ b/src/Perf/IIDOptimizer/ReferenceAssemblyResolver.cs @@ -0,0 +1,21 @@ +using Mono.Cecil; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace GuidPatch +{ + class ReferenceAssemblyResolver : DefaultAssemblyResolver + { + public ReferenceAssemblyResolver(IEnumerable references) + { + // Typically reference assemblies come in "ref packs" so all of the files in `references` live in the same folder, + // we can do a small optimization here by only adding unique directories to our custom AssemblyResolver + var uniqueDirectories = references + .Select((reference) => reference.Directory!.FullName) + .Distinct(); + + foreach (var dir in uniqueDirectories) { AddSearchDirectory(dir); } + } + } +} diff --git a/src/Perf/IIDOptimizer/SignatureEmitter.cs b/src/Perf/IIDOptimizer/SignatureEmitter.cs index a8b482ba6..f146a160f 100644 --- a/src/Perf/IIDOptimizer/SignatureEmitter.cs +++ b/src/Perf/IIDOptimizer/SignatureEmitter.cs @@ -42,10 +42,6 @@ public SignatureEmitter(TypeReference describedType, MethodDefinition guidDataGe { this.describedType = describedType; this.guidDataGetterMethod = guidDataGetterMethod; - - /* - * Initialize the logger with the OptimizerDir property - */ Logger = logger; } @@ -192,7 +188,7 @@ private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementati getterIL.Emit(OpCodes.Ldsfld, new FieldReference(cacheField.Name, cacheField.FieldType, instantiatedCacheType)); getterIL.Emit(OpCodes.Newobj, readOnlySpanOfByteArrayCtor); getterIL.Emit(OpCodes.Ret); - + // In the static constructor, calculate the guid bytes. var il = staticCtor.Body.GetILProcessor(); var signatureParts = new VariableDefinition[signatureSteps.Count]; @@ -269,7 +265,6 @@ private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementati break; case RuntimeCustomSignatureStep(MethodReference customSignatureMethod): { - /// TODO test this pat h // byte[] bytes = Encoding.UTF8.GetBytes(customSignatureMethod()) il.Emit(OpCodes.Call, utf8EncodingGetter); il.Emit(OpCodes.Call, customSignatureMethod); @@ -450,9 +445,15 @@ private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementati // Fix endianness, bytes var memoryExtensions = CecilExtensions.FindTypeReference(module, "System", "MemoryExtensions", "System.Memory", false); + + var reverseMethod_Generic = new MethodReference("Reverse", module.TypeSystem.Void, memoryExtensions) + { + HasThis = true, + }; + var reverseMethod = new MethodReference("Reverse", module.TypeSystem.Void, memoryExtensions) { - HasThis = false, + HasThis = true, }; var reverseMethodGenericParam = new GenericParameter(reverseMethod); reverseMethod.GenericParameters.Add(reverseMethodGenericParam); @@ -479,10 +480,10 @@ private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementati il.Emit(OpCodes.Ldc_I4_2); il.Emit(OpCodes.Call, spanSliceStartLengthMethod); il.Emit(OpCodes.Call, reverseMethod); - + // Encode rfc time/version/clock/reserved fields var getItemMethod = module.ImportReference(new MethodReference("get_Item", new ByReferenceType(span.Resolve().GenericParameters[0]), spanOfByte) { Parameters = { new ParameterDefinition(module.TypeSystem.Int32) } }); - + // t[7] = (byte) ((t[7] & 0x0f) | (5 << 4)); il.Emit(OpCodes.Ldloca, destination); il.Emit(OpCodes.Ldc_I4_7); @@ -515,6 +516,7 @@ private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementati var spanTemp = new VariableDefinition(spanOfByte); staticCtor.Body.Variables.Add(spanTemp); + il.Emit(OpCodes.Ldloca, destination); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Ldc_I4, 16); From 92715657992d58e3651b2c7599fa4bebbfc6996f Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Fri, 9 Jul 2021 12:56:30 -0700 Subject: [PATCH 15/24] Update reunion component + reunion references --- ...g.DispatcherQueueSynchronizationContext.cs | 2 +- src/Projections/Reunion/Reunion.csproj | 10 ++--- src/Tests/AuthoringTest/AuthoringTest.csproj | 17 ++++---- .../AuthoringWinUITest.vcxproj | 39 +++++++++---------- .../AuthoringWinUITest/packages.config | 10 ++--- .../ObjectLifetimeTests.Lifted.csproj | 2 +- src/WinRT.Runtime/WinRT.Runtime.csproj | 2 +- 7 files changed, 40 insertions(+), 42 deletions(-) diff --git a/src/Projections/Reunion/Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.cs b/src/Projections/Reunion/Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.cs index f1f5a7e5c..e883d9113 100644 --- a/src/Projections/Reunion/Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.cs +++ b/src/Projections/Reunion/Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.cs @@ -1,6 +1,6 @@ using System; using System.Threading; -using Microsoft.System; +using Microsoft.UI.Dispatching; namespace Microsoft.System { diff --git a/src/Projections/Reunion/Reunion.csproj b/src/Projections/Reunion/Reunion.csproj index 43014019c..bfd2b4a9c 100644 --- a/src/Projections/Reunion/Reunion.csproj +++ b/src/Projections/Reunion/Reunion.csproj @@ -12,13 +12,13 @@ - + build; buildtransitive; compile; runtime - + build; buildtransitive; compile; runtime - + build; buildtransitive; compile; runtime @@ -45,8 +45,8 @@ -include Windows.UI.Xaml.Media.Animation.ConditionallyIndependentlyAnimatableAttribute - $([MSBuild]::NormalizeDirectory('$(NuGetPackageRoot)', 'microsoft.projectreunion.winui', '0.5.7')) - $([MSBuild]::NormalizeDirectory('$(NuGetPackageRoot)', 'microsoft.projectreunion.foundation', '0.5.7')) + $([MSBuild]::NormalizeDirectory('$(NuGetPackageRoot)', 'microsoft.projectreunion.winui', '0.8.0')) + $([MSBuild]::NormalizeDirectory('$(NuGetPackageRoot)', 'microsoft.projectreunion.foundation', '0.8.0')) true key.snk diff --git a/src/Tests/AuthoringTest/AuthoringTest.csproj b/src/Tests/AuthoringTest/AuthoringTest.csproj index 691b01690..749eaaaf0 100644 --- a/src/Tests/AuthoringTest/AuthoringTest.csproj +++ b/src/Tests/AuthoringTest/AuthoringTest.csproj @@ -10,18 +10,17 @@ - - - - - - - + + + + + + - - + + diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj index 1dc4578a4..06c8a13d9 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj @@ -1,9 +1,9 @@  - - - - + + + + true @@ -146,14 +146,13 @@ + + {b6312ad1-a59e-4f3b-aa39-20b780fe9e15} + {ffa9a78b-f53f-43ee-af87-24a80f4c330a} TargetFramework=net5.0 - - {0a991d5f-bfee-4d2f-9aad-6ad06470a5df} - TargetFramework=net5.0 - {25244ced-966e-45f2-9711-1f51e951ff89} TargetFramework=net5.0 @@ -173,10 +172,10 @@ - - - - + + + + @@ -185,13 +184,13 @@ - - - - - - - - + + + + + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/packages.config b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/packages.config index c47ba540c..bc4c04ff0 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/packages.config +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/packages.config @@ -1,10 +1,10 @@  - - - - - + + + + + \ No newline at end of file diff --git a/src/Tests/ObjectLifetimeTests/ObjectLifetimeTests.Lifted.csproj b/src/Tests/ObjectLifetimeTests/ObjectLifetimeTests.Lifted.csproj index 21482df70..1ec3f602b 100644 --- a/src/Tests/ObjectLifetimeTests/ObjectLifetimeTests.Lifted.csproj +++ b/src/Tests/ObjectLifetimeTests/ObjectLifetimeTests.Lifted.csproj @@ -67,7 +67,7 @@ - 0.5.7 + 0.8.0 compile diff --git a/src/WinRT.Runtime/WinRT.Runtime.csproj b/src/WinRT.Runtime/WinRT.Runtime.csproj index 4a61f108a..125352f7a 100644 --- a/src/WinRT.Runtime/WinRT.Runtime.csproj +++ b/src/WinRT.Runtime/WinRT.Runtime.csproj @@ -4,7 +4,7 @@ netstandard2.0;net5.0 WinRT true - 8 + 9 full true Microsoft Corporation From 1eed5e32476dc0042e8cc5a4b815f1c88c566585 Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Fri, 9 Jul 2021 12:57:02 -0700 Subject: [PATCH 16/24] Update cswinrt.sln --- src/cswinrt.sln | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/cswinrt.sln b/src/cswinrt.sln index 0a68ff072..a7dd022c2 100644 --- a/src/cswinrt.sln +++ b/src/cswinrt.sln @@ -109,6 +109,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IIDOptimizer", "Perf\IIDOpt ProjectSection(ProjectDependencies) = postProject {25244CED-966E-45F2-9711-1F51E951FF89} = {25244CED-966E-45F2-9711-1F51E951FF89} EndProjectSection +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Reunion", "Projections\Reunion\Reunion.csproj", "{B6312AD1-A59E-4F3B-AA39-20B780FE9E15}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ObjectLifetimeTests.Lifted", "Tests\ObjectLifetimeTests\ObjectLifetimeTests.Lifted.csproj", "{BA7390DC-6CD3-44BB-B8B0-32BF2D068450}" @@ -442,14 +443,18 @@ Global {493C7729-2F21-4198-AB09-BDF56BF501D3}.Release|x64.Build.0 = Release|x64 {493C7729-2F21-4198-AB09-BDF56BF501D3}.Release|x86.ActiveCfg = Release|Win32 {493C7729-2F21-4198-AB09-BDF56BF501D3}.Release|x86.Build.0 = Release|Win32 - {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|ARM.ActiveCfg = Debug|Any CPU + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|ARM.Build.0 = Debug|Any CPU + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|ARM64.Build.0 = Debug|Any CPU {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|x64.ActiveCfg = Debug|Any CPU {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|x64.Build.0 = Debug|Any CPU {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|x86.ActiveCfg = Debug|Any CPU {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|x86.Build.0 = Debug|Any CPU - {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Release|Any CPU.Build.0 = Release|Any CPU + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Release|ARM.ActiveCfg = Release|Any CPU + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Release|ARM.Build.0 = Release|Any CPU + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Release|ARM64.ActiveCfg = Release|Any CPU + {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Release|ARM64.Build.0 = Release|Any CPU {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Release|x64.ActiveCfg = Release|Any CPU {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Release|x64.Build.0 = Release|Any CPU {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Release|x86.ActiveCfg = Release|Any CPU From 787f5441e94f064249419ce16a92b43c19484fb1 Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Tue, 13 Jul 2021 08:22:03 -0700 Subject: [PATCH 17/24] More Reunion/Lifted Lifetime test updates --- .../WinUIDesktopSample.csproj | 15 ++++---- .../AuthoringConsumptionTest.vcxproj | 36 ++++++++++--------- .../AuthoringConsumptionTest/packages.config | 9 ++--- src/Tests/ObjectLifetimeTests/App.xaml.cs | 3 +- src/Tests/ObjectLifetimeTests/AsyncQueue.cs | 1 + .../ObjectLifetimeTests.Lifted.csproj | 2 +- 6 files changed, 35 insertions(+), 31 deletions(-) diff --git a/src/Samples/WinUIDesktopSample/WinUIDesktopSample.csproj b/src/Samples/WinUIDesktopSample/WinUIDesktopSample.csproj index 7c54070c2..f076adcf8 100644 --- a/src/Samples/WinUIDesktopSample/WinUIDesktopSample.csproj +++ b/src/Samples/WinUIDesktopSample/WinUIDesktopSample.csproj @@ -13,6 +13,10 @@ x86;x64 true false + + true @@ -22,16 +26,11 @@ + + + - - - - compile; runtime - - $([MSBuild]::NormalizeDirectory('$(NuGetPackageRoot)', 'microsoft.projectreunion.winui', '0.5.7')) - $([MSBuild]::NormalizeDirectory('$(NuGetPackageRoot)', 'microsoft.projectreunion.foundation', '0.5.7')) + $([MSBuild]::NormalizeDirectory('$(NuGetPackageRoot)', 'microsoft.projectreunion.winui', '0.8.0')) + $([MSBuild]::NormalizeDirectory('$(NuGetPackageRoot)', 'microsoft.projectreunion.foundation', '0.8.0')) true key.snk diff --git a/src/Samples/WinUIDesktopSample/WinUIDesktopSample.csproj b/src/Samples/WinUIDesktopSample/WinUIDesktopSample.csproj index 7c54070c2..f076adcf8 100644 --- a/src/Samples/WinUIDesktopSample/WinUIDesktopSample.csproj +++ b/src/Samples/WinUIDesktopSample/WinUIDesktopSample.csproj @@ -13,6 +13,10 @@ x86;x64 true false + + true @@ -22,16 +26,11 @@ + + + - - - - compile; runtime - + so they may be passed as an option to the IIDOptimizer in the target that invokes the tool --> + + obj\IIDOptimizer\ $(CsWinRTPath)build\tools\IIDOptimizer\ @(BuiltProjectOutputGroupKeyOutput->'%(Identity)') - - $(CsWinRTPath)lib\net5.0\ - @(ReferencePathWithRefAssemblies->'--refs %(Identity)', ' ') - + - + $([System.IO.Directory]::GetParent($(CsWinRTIIDOptimizerTargetAssembly))) diff --git a/nuget/NOTICE.txt b/nuget/NOTICE.txt index 8e570fdba..7d966c8da 100644 --- a/nuget/NOTICE.txt +++ b/nuget/NOTICE.txt @@ -17,7 +17,7 @@ required to debug changes to any libraries licensed under the GNU Lesser General --------------------------------------------------------- -Mono.Cecil 0.11.3 - MIT +Mono.Cecil 0.11.4 - MIT Copyright (c) 2008 - 2015 Jb Evain Copyright (c) 2008 - 2011 Novell, Inc. diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 4465fb6a7..cf12ec67f 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -28,7 +28,6 @@ $(MSBuildThisFileDirectory)Perf\IIDOptimizer\bin\$(Configuration)\net5.0\ - $(MSBuildThisFileDirectory)WinRT.Runtime\bin\$(Configuration)\net5.0\ diff --git a/src/Perf/IIDOptimizer/GuidPatcher.cs b/src/Perf/IIDOptimizer/GuidPatcher.cs index 48d4756f0..092804c35 100644 --- a/src/Perf/IIDOptimizer/GuidPatcher.cs +++ b/src/Perf/IIDOptimizer/GuidPatcher.cs @@ -1,5 +1,4 @@ using Mono.Cecil; -using Mono.Cecil.Pdb; using Mono.Cecil.Cil; using System; using System.Collections.Generic; @@ -30,7 +29,6 @@ class GuidPatcher private readonly TypeDefinition guidImplementationDetailsType; private readonly TypeDefinition guidDataBlockType; private SignatureGenerator signatureGenerator; - private Logger Logger { get; } // OptimizerDir is the path our current process should use to write logs and patched DLLs to public string OptimizerDir @@ -40,11 +38,6 @@ public string OptimizerDir public GuidPatcher(string assemblyPath, IAssemblyResolver assemblyResolver, AssemblyDefinition winRTRuntime) { - /* - * Initialize the logger with the OptimizerDir property - */ - Logger = new Logger(OptimizerDir, "log_iidoptimizer.txt"); - var readerParameters = new ReaderParameters(ReadingMode.Deferred) { ReadWrite = true, @@ -120,7 +113,7 @@ public GuidPatcher(string assemblyPath, IAssemblyResolver assemblyResolver, Asse getHelperTypeMethod = typeExtensionsType.Methods.First(m => m.Name == "GetHelperType"); } - signatureGenerator = new SignatureGenerator(assembly, guidAttributeType!, winRTRuntimeAssembly, Logger); + signatureGenerator = new SignatureGenerator(assembly, guidAttributeType!, winRTRuntimeAssembly); } public int ProcessAssembly() @@ -142,7 +135,6 @@ where method.HasBody numPatches += ProcessMethodBody(method.Body, getTypeFromHandleMethod, getIidMethod!, createIidMethod!); } - Logger.Close(); return numPatches; } @@ -198,7 +190,7 @@ private bool PatchGenericTypeIID(MethodBody body, int startILIndex, TypeReferenc guidImplementationDetailsType.Methods.Add(guidDataMethod); - var emitter = new SignatureEmitter(type, guidDataMethod, Logger); + var emitter = new SignatureEmitter(type, guidDataMethod); VisitSignature(rootSignaturePart, emitter); emitter.EmitGuidGetter(guidDataBlockType, guidImplementationDetailsType, readOnlySpanOfByte, readOnlySpanOfByteCtor, guidGeneratorType!); @@ -372,7 +364,6 @@ private int ProcessMethodBody(MethodBody body, MethodDefinition getTypeFromHandl } catch (Exception ex) { - Logger.Log($"Exception thrown during patching {body.Method.FullName}: {ex}"); Debug.WriteLine($"Exception thrown during patching {body.Method.FullName}: {ex}"); } } diff --git a/src/Perf/IIDOptimizer/IIDOptimizer.csproj b/src/Perf/IIDOptimizer/IIDOptimizer.csproj index 5f4eecbe3..a3b0e10ca 100644 --- a/src/Perf/IIDOptimizer/IIDOptimizer.csproj +++ b/src/Perf/IIDOptimizer/IIDOptimizer.csproj @@ -6,14 +6,9 @@ enable - - - https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-libraries/nuget/v3/index.json - - - + diff --git a/src/Perf/IIDOptimizer/Logger.cs b/src/Perf/IIDOptimizer/Logger.cs deleted file mode 100644 index 0f8dabee1..000000000 --- a/src/Perf/IIDOptimizer/Logger.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.IO; - -namespace GuidPatch -{ - class Logger - { - public Logger(string parentDir, string fileName) - { - string logFile = Path.Combine(parentDir, fileName); - fileLogger = File.CreateText(logFile); - } - - public void Log(string text) - { - fileLogger?.WriteLine(text); - } - - public void Close() - { - fileLogger?.Close(); - } - - private readonly TextWriter fileLogger; - } - -} diff --git a/src/Perf/IIDOptimizer/Program.cs b/src/Perf/IIDOptimizer/Program.cs index a5ef49e20..29eb7f46e 100644 --- a/src/Perf/IIDOptimizer/Program.cs +++ b/src/Perf/IIDOptimizer/Program.cs @@ -13,55 +13,42 @@ class Program static readonly Option _targetAssembly = new Option ( - name: "--targetAssembly", - description: "The assembly to perform GUID optimizations on.", + alias: "--targetAssembly", + description: "The assembly to perform GUID lookup optimizations on.", argumentType: typeof(string), arity: ArgumentArity.ExactlyOne ); - - static readonly Option _runtimePath = - new Option - ( - name: "--runtimePath", - description: "The path to the folder used to resolve WinRT.Runtime.dll assembly.", - argumentType: typeof(string), - arity: ArgumentArity.ExactlyOne - ); - + static readonly Option _references = new Option ( - name: "--references", + alias: "--references", description: "Reference assemblies used when compiling the target assembly.", argumentType: typeof(FileInfo[]), arity: ArgumentArity.ZeroOrMore ); - static async Task Main(string[] args) { var rootCommand = new RootCommand { }; // friendlier option names _targetAssembly.AddAlias("--target"); - _runtimePath.AddAlias("--runtime"); _references.AddAlias("--refs"); rootCommand.AddOption(_targetAssembly); - rootCommand.AddOption(_runtimePath); rootCommand.AddOption(_references); - rootCommand.Handler = CommandHandler.Create>(GuidPatch); + rootCommand.Handler = CommandHandler.Create>(GuidPatch); await rootCommand.InvokeAsync(args); } - private static int GuidPatch(string targetAssembly, string runtimePath, IEnumerable references) + private static int GuidPatch(string targetAssembly, IEnumerable references) { - // pass targetAssembly here and update ReferenceAssemblyResolver to use it when resolving ==> can patch WinRT.Runtime itself var resolver = new ReferenceAssemblyResolver(references); try { AssemblyDefinition winRTRuntimeAssembly = resolver.Resolve(new AssemblyNameReference("WinRT.Runtime", default)); - + Directory.CreateDirectory("obj\\IIDOptimizer"); var guidPatcher = new GuidPatcher( diff --git a/src/Perf/IIDOptimizer/SignatureEmitter.cs b/src/Perf/IIDOptimizer/SignatureEmitter.cs index 3f1f6e0c3..2dceaf67e 100644 --- a/src/Perf/IIDOptimizer/SignatureEmitter.cs +++ b/src/Perf/IIDOptimizer/SignatureEmitter.cs @@ -1,7 +1,6 @@ using Mono.Cecil; using Mono.Cecil.Cil; using System; -using System.Buffers.Binary; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -20,14 +19,12 @@ sealed class SignatureEmitter private readonly Dictionary getterParameterToOriginalGenericParameterMapping = new(); private readonly TypeReference describedType; private readonly MethodDefinition guidDataGetterMethod; - private Logger Logger { get; set; } // OptimizerDir is the path our current process should use to write logs and patched DLLs to public string OptimizerDir { get { return "obj\\IIDOptimizer"; } } - public IReadOnlyDictionary GenericParameterMapping => getterParameterToOriginalGenericParameterMapping; record SignatureStep; @@ -38,11 +35,10 @@ sealed record RuntimeGenericSignatureStep(GenericParameter OriginalTypeParameter sealed record RuntimeCustomSignatureStep(MethodReference method) : SignatureStep; - public SignatureEmitter(TypeReference describedType, MethodDefinition guidDataGetterMethod, Logger logger) + public SignatureEmitter(TypeReference describedType, MethodDefinition guidDataGetterMethod) { this.describedType = describedType; this.guidDataGetterMethod = guidDataGetterMethod; - Logger = logger; } public void PushString(string str) @@ -159,7 +155,7 @@ private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementati // Create generic class with static array field to cache result. var cacheType = new TypeDefinition(null, $"{describedType.FullName}", TypeAttributes.NestedPrivate | TypeAttributes.Abstract | TypeAttributes.Sealed, module.ImportReference(module.TypeSystem.Object)); - Dictionary getterMethodGensToCacheTypeGens = new(); + Dictionary getterMethodGensToCacheTypeGens = new(); for (int i = 0; i < guidDataGetterMethod.GenericParameters.Count; i++) { @@ -192,7 +188,7 @@ private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementati getterIL.Emit(OpCodes.Ldsfld, new FieldReference(cacheField.Name, cacheField.FieldType, instantiatedCacheType)); getterIL.Emit(OpCodes.Newobj, readOnlySpanOfByteArrayCtor); getterIL.Emit(OpCodes.Ret); - + // In the static constructor, calculate the guid bytes. var il = staticCtor.Body.GetILProcessor(); var signatureParts = new VariableDefinition[signatureSteps.Count]; @@ -333,24 +329,24 @@ private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementati HasThis = true }); - // import a Span instead of Span - var spanOfSpanElement = new GenericInstanceType(span) { GenericArguments = { span.GenericParameters[0] } }; - + // return a Span instead of Span + var spanOfSpanElement = new GenericInstanceType(span) { GenericArguments = { span.Resolve().GenericParameters[0] } }; + var spanSliceStartMethod = module.ImportReference( - new MethodReference("Slice", spanOfByte, spanOfSpanElement) + new MethodReference("Slice", spanOfSpanElement, spanOfByte) { HasThis = true, Parameters = { new ParameterDefinition(module.TypeSystem.Int32) } }); var spanSliceStartLengthMethod = module.ImportReference( - new MethodReference("Slice", spanOfByte, spanOfSpanElement) + new MethodReference("Slice", spanOfSpanElement, spanOfByte) { HasThis = true, Parameters = { new ParameterDefinition(module.TypeSystem.Int32), new ParameterDefinition(module.TypeSystem.Int32) } }); - var readOnlySpanOfByteLength = module.ImportReference(new MethodReference("get_Length", module.TypeSystem.Int32, readOnlySpanOfByte)); + var readOnlySpanOfByteLength = module.ImportReference(new MethodReference("get_Length", module.TypeSystem.Int32, readOnlySpanOfByte) { HasThis = true }); var fullSignatureBuffer = new VariableDefinition(spanOfByte); staticCtor.Body.Variables.Add(fullSignatureBuffer); @@ -454,19 +450,15 @@ private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementati il.Emit(OpCodes.Call, spanToReadOnlySpan); il.Emit(OpCodes.Ldloc, destination); il.Emit(OpCodes.Call, hashDataMethod); + il.Emit(OpCodes.Pop); // Fix endianness, bytes var memoryExtensions = CecilExtensions.FindTypeReference(module, "System", "MemoryExtensions", "System.Memory", false); - var reverseMethod_Generic = new MethodReference("Reverse", module.TypeSystem.Void, memoryExtensions) - { - HasThis = true, - }; + var reverseMethod_Generic = new MethodReference("Reverse", module.TypeSystem.Void, memoryExtensions) { }; + + var reverseMethod = new MethodReference("Reverse", module.TypeSystem.Void, memoryExtensions) { }; - var reverseMethod = new MethodReference("Reverse", module.TypeSystem.Void, memoryExtensions) - { - HasThis = true, - }; var reverseMethodGenericParam = new GenericParameter(reverseMethod); reverseMethod.GenericParameters.Add(reverseMethodGenericParam); reverseMethod.Parameters.Add(new ParameterDefinition(new GenericInstanceType(span) { GenericArguments = { reverseMethodGenericParam } })); @@ -494,7 +486,12 @@ private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementati il.Emit(OpCodes.Call, reverseMethod); // Encode rfc time/version/clock/reserved fields - var getItemMethod = module.ImportReference(new MethodReference("get_Item", new ByReferenceType(span.Resolve().GenericParameters[0]), spanOfByte) { Parameters = { new ParameterDefinition(module.TypeSystem.Int32) } }); + var getItemMethod = module.ImportReference( + new MethodReference("get_Item", new ByReferenceType(span.Resolve().GenericParameters[0]), spanOfByte) + { + Parameters = { new ParameterDefinition(module.TypeSystem.Int32) }, + HasThis = true + }); // t[7] = (byte) ((t[7] & 0x0f) | (5 << 4)); il.Emit(OpCodes.Ldloca, destination); @@ -524,7 +521,12 @@ private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementati // cacheField = destination.Slice(0, 16).ToArray() - var toArrayMethod = module.ImportReference(new MethodReference("ToArray", new ArrayType(span.Resolve().GenericParameters[0]), spanOfByte)); + var toArrayMethod = module.ImportReference( + new MethodReference("ToArray", new ArrayType(span.Resolve().GenericParameters[0]), spanOfByte) + { + HasThis = true + }); + var spanTemp = new VariableDefinition(spanOfByte); staticCtor.Body.Variables.Add(spanTemp); diff --git a/src/Perf/IIDOptimizer/SignatureGenerator.cs b/src/Perf/IIDOptimizer/SignatureGenerator.cs index 07d0958b0..185e06d6e 100644 --- a/src/Perf/IIDOptimizer/SignatureGenerator.cs +++ b/src/Perf/IIDOptimizer/SignatureGenerator.cs @@ -58,7 +58,7 @@ sealed class SignatureGenerator private readonly TypeDefinition guidAttributeType; private readonly AssemblyDefinition winRTRuntimeAssembly; - public SignatureGenerator(AssemblyDefinition assembly, TypeDefinition guidAttributeType, AssemblyDefinition runtimeAssembly, Logger logger) + public SignatureGenerator(AssemblyDefinition assembly, TypeDefinition guidAttributeType, AssemblyDefinition runtimeAssembly) { this.assembly = assembly; this.guidAttributeType = guidAttributeType; diff --git a/src/Projections/Reunion/Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.cs b/src/Projections/Reunion/Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.cs index e883d9113..f1f5a7e5c 100644 --- a/src/Projections/Reunion/Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.cs +++ b/src/Projections/Reunion/Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.cs @@ -1,6 +1,6 @@ using System; using System.Threading; -using Microsoft.UI.Dispatching; +using Microsoft.System; namespace Microsoft.System { diff --git a/src/Projections/Reunion/Reunion.csproj b/src/Projections/Reunion/Reunion.csproj index bfd2b4a9c..43014019c 100644 --- a/src/Projections/Reunion/Reunion.csproj +++ b/src/Projections/Reunion/Reunion.csproj @@ -12,13 +12,13 @@ - + build; buildtransitive; compile; runtime - + build; buildtransitive; compile; runtime - + build; buildtransitive; compile; runtime @@ -45,8 +45,8 @@ -include Windows.UI.Xaml.Media.Animation.ConditionallyIndependentlyAnimatableAttribute - $([MSBuild]::NormalizeDirectory('$(NuGetPackageRoot)', 'microsoft.projectreunion.winui', '0.8.0')) - $([MSBuild]::NormalizeDirectory('$(NuGetPackageRoot)', 'microsoft.projectreunion.foundation', '0.8.0')) + $([MSBuild]::NormalizeDirectory('$(NuGetPackageRoot)', 'microsoft.projectreunion.winui', '0.5.7')) + $([MSBuild]::NormalizeDirectory('$(NuGetPackageRoot)', 'microsoft.projectreunion.foundation', '0.5.7')) true key.snk diff --git a/src/Projections/Test/Test.csproj b/src/Projections/Test/Test.csproj index 1fc3d97f9..2dd8d8a4e 100644 --- a/src/Projections/Test/Test.csproj +++ b/src/Projections/Test/Test.csproj @@ -13,8 +13,8 @@ - + diff --git a/src/Samples/WinUIDesktopSample/WinUIDesktopSample.csproj b/src/Samples/WinUIDesktopSample/WinUIDesktopSample.csproj index f076adcf8..7c54070c2 100644 --- a/src/Samples/WinUIDesktopSample/WinUIDesktopSample.csproj +++ b/src/Samples/WinUIDesktopSample/WinUIDesktopSample.csproj @@ -13,10 +13,6 @@ x86;x64 true false - - true @@ -26,11 +22,16 @@ - - - + + + + compile; runtime + - true + - - - - - - + + + + + + + - - + + diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest (Package)/AuthoringWinUITest (Package).wapproj b/src/Tests/AuthoringWinUITest/AuthoringWinUITest (Package)/AuthoringWinUITest (Package).wapproj index 36bba7db4..116ca8e36 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest (Package)/AuthoringWinUITest (Package).wapproj +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest (Package)/AuthoringWinUITest (Package).wapproj @@ -41,6 +41,7 @@ 10.0.17763.0 en-US false + $(MSBuildThisFileDirectory)build\ ..\AuthoringWinUITest\AuthoringWinUITest.vcxproj <_WinMDPlatform>$(Platform) <_WinMDPlatform Condition="'$(Platform)' == 'Win32'">x86 @@ -78,4 +79,5 @@ + \ No newline at end of file diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest (Package)/build/Microsoft.WinUI.AppX.targets b/src/Tests/AuthoringWinUITest/AuthoringWinUITest (Package)/build/Microsoft.WinUI.AppX.targets new file mode 100644 index 000000000..307641788 --- /dev/null +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest (Package)/build/Microsoft.WinUI.AppX.targets @@ -0,0 +1,236 @@ + + + + + + + + + + + + $(MSBuildThisFileDirectory) + + + $(WinUIClassRegistrationsDir.Substring(0,$(WinUIClassRegistrationsDir.IndexOf(';')))) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(MSBuildWarningsAsMessages); + + + APPX1707; + + + $(MSBuildWarningsAsMessages); + + + MSB3268; + + + + + + + + + Windows + 10.0 + en-US + + + + + + <_MuxRuntimeIdentifier Condition="'$(Platform)' == 'Win32'">win10-x86 + <_MuxRuntimeIdentifier Condition="'$(Platform)' != 'Win32'">win10-$(Platform) + + + + $([MSBuild]::MakeRelative($(MSBuildThisFileDirectory)..\runtimes\$(_MuxRuntimeIdentifier)\native\, %(RootDir)%(Directory))) + + + + + + + + + %(WapProjPackageFile.DestinationSubDirectory)%(TargetPath) + + + %(UploadWapProjPackageFile.DestinationSubDirectory)%(TargetPath) + + + + + + + + + + + + + + + + + + + + + UAP + + + + diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/App.xaml.cpp b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/App.xaml.cpp index 22e677eb5..50d0f5ca7 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/App.xaml.cpp +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/App.xaml.cpp @@ -8,11 +8,6 @@ using namespace Windows::Foundation; using namespace Microsoft::UI::Xaml; using namespace Microsoft::UI::Xaml::Controls; using namespace Microsoft::UI::Xaml::Navigation; -using namespace Microsoft::UI::Xaml::Controls::Primitives; -using namespace Microsoft::UI::Xaml::Data; -using namespace Microsoft::UI::Xaml::Input; -using namespace Microsoft::UI::Xaml::Interop; -using namespace Microsoft::UI::Xaml::Media; using namespace AuthoringWinUITest; using namespace AuthoringWinUITest::implementation; @@ -26,6 +21,7 @@ using namespace AuthoringWinUITest::implementation; App::App() { InitializeComponent(); + Suspending({ this, &App::OnSuspending }); #if defined _DEBUG && !defined DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION UnhandledException([this](IInspectable const&, UnhandledExceptionEventArgs const& e) diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj index 06c8a13d9..4c158c7dc 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/AuthoringWinUITest.vcxproj @@ -1,9 +1,6 @@  - - - - + true @@ -146,13 +143,14 @@ - - {b6312ad1-a59e-4f3b-aa39-20b780fe9e15} - {ffa9a78b-f53f-43ee-af87-24a80f4c330a} TargetFramework=net5.0 + + {0a991d5f-bfee-4d2f-9aad-6ad06470a5df} + TargetFramework=net5.0 + {25244ced-966e-45f2-9711-1f51e951ff89} TargetFramework=net5.0 @@ -172,10 +170,7 @@ - - - - + @@ -184,13 +179,7 @@ - - - - - - - - + + \ No newline at end of file diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/Directory.Build.targets b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/Directory.Build.targets index 2703424c4..d0d6c4c99 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/Directory.Build.targets +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/Directory.Build.targets @@ -1,5 +1,5 @@ - + CopyTestAssets;$(PrepareForRunDependsOn) @@ -10,7 +10,7 @@ DestinationFiles="$(OutDir)WinRT.Host.dll" UseHardlinksIfPossible="false" SkipUnchangedFiles="true" /> - + diff --git a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/packages.config b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/packages.config index bc4c04ff0..7d3974eb9 100644 --- a/src/Tests/AuthoringWinUITest/AuthoringWinUITest/packages.config +++ b/src/Tests/AuthoringWinUITest/AuthoringWinUITest/packages.config @@ -1,10 +1,6 @@  - - - - - + \ No newline at end of file diff --git a/src/Tests/ObjectLifetimeTests/App.xaml.cs b/src/Tests/ObjectLifetimeTests/App.xaml.cs index be4108951..f5bda2290 100644 --- a/src/Tests/ObjectLifetimeTests/App.xaml.cs +++ b/src/Tests/ObjectLifetimeTests/App.xaml.cs @@ -1,5 +1,4 @@ -using Microsoft.UI.Dispatching; -using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls.Primitives; using Microsoft.UI.Xaml.Data; diff --git a/src/Tests/ObjectLifetimeTests/AsyncQueue.cs b/src/Tests/ObjectLifetimeTests/AsyncQueue.cs index ae5b5268c..37a131312 100644 --- a/src/Tests/ObjectLifetimeTests/AsyncQueue.cs +++ b/src/Tests/ObjectLifetimeTests/AsyncQueue.cs @@ -4,7 +4,6 @@ using System.Runtime.CompilerServices; using System.Text; using System.Threading; -using Microsoft.UI.Dispatching; using System.Threading.Tasks; using Microsoft.System; using Microsoft.UI.Xaml; diff --git a/src/Tests/ObjectLifetimeTests/ObjectLifetimeTests.Lifted.csproj b/src/Tests/ObjectLifetimeTests/ObjectLifetimeTests.Lifted.csproj index 233a3f161..21482df70 100644 --- a/src/Tests/ObjectLifetimeTests/ObjectLifetimeTests.Lifted.csproj +++ b/src/Tests/ObjectLifetimeTests/ObjectLifetimeTests.Lifted.csproj @@ -12,7 +12,7 @@ false false - MSIX + Desktop @@ -67,7 +67,7 @@ - 0.8.0 + 0.5.7 compile diff --git a/src/Tests/TestComponentCSharp/ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.cpp b/src/Tests/TestComponentCSharp/ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.cpp new file mode 100644 index 000000000..638101521 --- /dev/null +++ b/src/Tests/TestComponentCSharp/ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.cpp @@ -0,0 +1,19 @@ +#include "pch.h" +#include "ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.h" +#include "ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.g.cpp" + +namespace winrt::TestComponentCSharp::implementation +{ + winrt::event_token ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz::EventForAVeryLongClassName(winrt::Windows::Foundation::TypedEventHandler const& handler) + { + return _theEvent.add(handler); + } + void ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz::EventForAVeryLongClassName(winrt::event_token const& token) noexcept + { + _theEvent.remove(token); + } + void ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz::InvokeEvent() + { + _theEvent(*this, *this); + } +} diff --git a/src/Tests/TestComponentCSharp/ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.h b/src/Tests/TestComponentCSharp/ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.h new file mode 100644 index 000000000..50b5f6d22 --- /dev/null +++ b/src/Tests/TestComponentCSharp/ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.h @@ -0,0 +1,22 @@ +#pragma once +#include "ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.g.h" + +namespace winrt::TestComponentCSharp::implementation +{ + struct ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz : ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzT + { + ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz() = default; + + winrt::event> _theEvent; + + winrt::event_token EventForAVeryLongClassName(winrt::Windows::Foundation::TypedEventHandler const& handler); + void EventForAVeryLongClassName(winrt::event_token const& token) noexcept; + void InvokeEvent(); + }; +} +namespace winrt::TestComponentCSharp::factory_implementation +{ + struct ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz : ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzT + { + }; +} diff --git a/src/Tests/TestComponentCSharp/TestComponentCSharp.idl b/src/Tests/TestComponentCSharp/TestComponentCSharp.idl index a508fdede..9c0a254d3 100644 --- a/src/Tests/TestComponentCSharp/TestComponentCSharp.idl +++ b/src/Tests/TestComponentCSharp/TestComponentCSharp.idl @@ -402,6 +402,15 @@ namespace TestComponentCSharp static Object BadRuntimeClassName{ get; }; } + runtimeclass ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz + { + ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz(); + + event Windows.Foundation.TypedEventHandler EventForAVeryLongClassName; + + void InvokeEvent(); + } + [threading(sta), marshaling_behavior(standard)] runtimeclass NonAgileClass { diff --git a/src/Tests/TestComponentCSharp/TestComponentCSharp.vcxproj b/src/Tests/TestComponentCSharp/TestComponentCSharp.vcxproj index 01d56f880..4112b1cff 100644 --- a/src/Tests/TestComponentCSharp/TestComponentCSharp.vcxproj +++ b/src/Tests/TestComponentCSharp/TestComponentCSharp.vcxproj @@ -64,6 +64,7 @@ + @@ -77,6 +78,7 @@ + Create diff --git a/src/Tests/TestComponentCSharp/TestComponentCSharp.vcxproj.filters b/src/Tests/TestComponentCSharp/TestComponentCSharp.vcxproj.filters index 91f509b7c..c1399fa56 100644 --- a/src/Tests/TestComponentCSharp/TestComponentCSharp.vcxproj.filters +++ b/src/Tests/TestComponentCSharp/TestComponentCSharp.vcxproj.filters @@ -16,6 +16,7 @@ + @@ -25,6 +26,7 @@ + diff --git a/src/Tests/UnitTest/TestComponentCSharp_Tests.cs b/src/Tests/UnitTest/TestComponentCSharp_Tests.cs index 44f2515f1..dd62e0805 100644 --- a/src/Tests/UnitTest/TestComponentCSharp_Tests.cs +++ b/src/Tests/UnitTest/TestComponentCSharp_Tests.cs @@ -49,6 +49,20 @@ public class TestCSharp public TestCSharp() { TestObject = new Class(); + } + + + // Test a fix for a bug in Mono.Cecil that was affecting the IIDOptimizer when it encountered long class names + [Fact] + public void TestLongClassNameEventSource() + { + bool flag = false; + var long_class_name = new ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz(); + long_class_name.EventForAVeryLongClassName += + (ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz sender, ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz args) + => flag = true; + long_class_name.InvokeEvent(); + Assert.True(flag); } [Fact] diff --git a/src/Tests/UnitTest/UnitTest.csproj b/src/Tests/UnitTest/UnitTest.csproj index dd096136a..a00ffb573 100644 --- a/src/Tests/UnitTest/UnitTest.csproj +++ b/src/Tests/UnitTest/UnitTest.csproj @@ -9,11 +9,12 @@ true true false + true - + diff --git a/src/WinRT.Runtime/Directory.Build.targets b/src/WinRT.Runtime/Directory.Build.targets deleted file mode 100644 index 13d5edf78..000000000 --- a/src/WinRT.Runtime/Directory.Build.targets +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - C:\Users\jlarkin\.nuget\packages\microsoft.windows.cswinrt\1.2.6\lib\net5.0 - $(CsWinRTPath)build\tools\GuidPatch\ - @(BuiltProjectOutputGroupKeyOutput->'%(Identity)') - $([System.IO.Directory]::GetParent($(CsWinRTIIDOptimizerInput))) - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/cswinrt.sln b/src/cswinrt.sln index 0b769577e..ec7fbc5d1 100644 --- a/src/cswinrt.sln +++ b/src/cswinrt.sln @@ -37,6 +37,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestComponent", "TestWinRT\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinRT.Runtime", "WinRT.Runtime\WinRT.Runtime.csproj", "{25244CED-966E-45F2-9711-1F51E951FF89}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinUIDesktopSample", "Samples\WinUIDesktopSample\WinUIDesktopSample.csproj", "{8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test", "Projections\Test\Test.csproj", "{C6D580C5-7037-4733-B933-916FF400AFE2}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projections", "Projections", "{6D41796B-9904-40B8-BBCB-40B2D1BAE44B}" @@ -101,6 +103,8 @@ Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "AuthoringWinUITest (Package EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AuthoringWinUITest", "Tests\AuthoringWinUITest\AuthoringWinUITest\AuthoringWinUITest.vcxproj", "{493C7729-2F21-4198-AB09-BDF56BF501D3}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ObjectLifetimeTests.Lifted", "Tests\ObjectLifetimeTests\ObjectLifetimeTests.Lifted.csproj", "{BA7390DC-6CD3-44BB-B8B0-32BF2D068450}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Perf", "Perf", "{539DBDEF-3B49-4503-9BD3-7EB83C2179CB}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IIDOptimizer", "Perf\IIDOptimizer\IIDOptimizer.csproj", "{AE3B0611-2FBB-42AB-A245-B4E79868A5F9}" @@ -188,6 +192,18 @@ Global {25244CED-966E-45F2-9711-1F51E951FF89}.Release|x64.Build.0 = Release|Any CPU {25244CED-966E-45F2-9711-1F51E951FF89}.Release|x86.ActiveCfg = Release|Any CPU {25244CED-966E-45F2-9711-1F51E951FF89}.Release|x86.Build.0 = Release|Any CPU + {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Debug|ARM.ActiveCfg = Debug|x86 + {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Debug|ARM64.ActiveCfg = Debug|x86 + {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Debug|x64.ActiveCfg = Debug|x64 + {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Debug|x64.Build.0 = Debug|x64 + {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Debug|x86.ActiveCfg = Debug|x86 + {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Debug|x86.Build.0 = Debug|x86 + {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Release|ARM.ActiveCfg = Release|x86 + {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Release|ARM64.ActiveCfg = Release|x86 + {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Release|x64.ActiveCfg = Release|x64 + {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Release|x64.Build.0 = Release|x64 + {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Release|x86.ActiveCfg = Release|x86 + {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D}.Release|x86.Build.0 = Release|x86 {C6D580C5-7037-4733-B933-916FF400AFE2}.Debug|ARM.ActiveCfg = Debug|x86 {C6D580C5-7037-4733-B933-916FF400AFE2}.Debug|ARM64.ActiveCfg = Debug|x86 {C6D580C5-7037-4733-B933-916FF400AFE2}.Debug|x64.ActiveCfg = Debug|x64 @@ -427,6 +443,20 @@ Global {493C7729-2F21-4198-AB09-BDF56BF501D3}.Release|x64.Build.0 = Release|x64 {493C7729-2F21-4198-AB09-BDF56BF501D3}.Release|x86.ActiveCfg = Release|Win32 {493C7729-2F21-4198-AB09-BDF56BF501D3}.Release|x86.Build.0 = Release|Win32 + {BA7390DC-6CD3-44BB-B8B0-32BF2D068450}.Debug|ARM.ActiveCfg = Debug|x86 + {BA7390DC-6CD3-44BB-B8B0-32BF2D068450}.Debug|ARM64.ActiveCfg = Debug|arm64 + {BA7390DC-6CD3-44BB-B8B0-32BF2D068450}.Debug|ARM64.Build.0 = Debug|arm64 + {BA7390DC-6CD3-44BB-B8B0-32BF2D068450}.Debug|x64.ActiveCfg = Debug|x64 + {BA7390DC-6CD3-44BB-B8B0-32BF2D068450}.Debug|x64.Build.0 = Debug|x64 + {BA7390DC-6CD3-44BB-B8B0-32BF2D068450}.Debug|x86.ActiveCfg = Debug|x86 + {BA7390DC-6CD3-44BB-B8B0-32BF2D068450}.Debug|x86.Build.0 = Debug|x86 + {BA7390DC-6CD3-44BB-B8B0-32BF2D068450}.Release|ARM.ActiveCfg = Release|x86 + {BA7390DC-6CD3-44BB-B8B0-32BF2D068450}.Release|ARM64.ActiveCfg = Release|arm64 + {BA7390DC-6CD3-44BB-B8B0-32BF2D068450}.Release|ARM64.Build.0 = Release|arm64 + {BA7390DC-6CD3-44BB-B8B0-32BF2D068450}.Release|x64.ActiveCfg = Release|x64 + {BA7390DC-6CD3-44BB-B8B0-32BF2D068450}.Release|x64.Build.0 = Release|x64 + {BA7390DC-6CD3-44BB-B8B0-32BF2D068450}.Release|x86.ActiveCfg = Release|x86 + {BA7390DC-6CD3-44BB-B8B0-32BF2D068450}.Release|x86.Build.0 = Release|x86 {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|ARM.ActiveCfg = Debug|Any CPU {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|ARM.Build.0 = Debug|Any CPU {AE3B0611-2FBB-42AB-A245-B4E79868A5F9}.Debug|ARM64.ActiveCfg = Debug|Any CPU @@ -463,6 +493,7 @@ Global {7E3A9AB3-8CBB-4B9C-BA76-0FE7108DCAEB} = {CFB651EC-DAA4-4A11-ABCD-C77F90602EB5} {9A9F52CA-F624-43A4-B5EF-C50861F584C2} = {CFB651EC-DAA4-4A11-ABCD-C77F90602EB5} {2954F343-85A7-46F5-A3F3-F106FDD13900} = {CFB651EC-DAA4-4A11-ABCD-C77F90602EB5} + {8E6FBCB2-B0C1-4E92-8AEB-2A11564E6E0D} = {6DA854DB-57BF-4FDD-AFF6-F70C965F48F6} {C6D580C5-7037-4733-B933-916FF400AFE2} = {6D41796B-9904-40B8-BBCB-40B2D1BAE44B} {FFA9A78B-F53F-43EE-AF87-24A80F4C330A} = {6D41796B-9904-40B8-BBCB-40B2D1BAE44B} {0A991D5F-BFEE-4D2F-9AAD-6AD06470A5DF} = {6D41796B-9904-40B8-BBCB-40B2D1BAE44B} From dc4385d78679569f7255956c2c004bfe3ab1032b Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Thu, 15 Jul 2021 16:49:35 -0700 Subject: [PATCH 23/24] Don't patch twice --- nuget/Microsoft.Windows.CsWinRT.targets | 27 ++++++++------ src/Perf/IIDOptimizer/GuidPatcher.cs | 26 ++----------- src/Perf/IIDOptimizer/Program.cs | 49 ++++++++++++++++++++----- 3 files changed, 57 insertions(+), 45 deletions(-) diff --git a/nuget/Microsoft.Windows.CsWinRT.targets b/nuget/Microsoft.Windows.CsWinRT.targets index 3bf972753..cc0645f3a 100644 --- a/nuget/Microsoft.Windows.CsWinRT.targets +++ b/nuget/Microsoft.Windows.CsWinRT.targets @@ -135,24 +135,27 @@ $(CsWinRTIncludeWinRTInterop) - - - obj\IIDOptimizer\ - + + $(CsWinRTPath)build\tools\IIDOptimizer\ + We are using the output's .dll from the *obj* folder. + After linking, the output's .dll gets copied to the bin folder. These targets run before linking. --> @(BuiltProjectOutputGroupKeyOutput->'%(Identity)') - + + $([MSBuild]::NormalizeDirectory('$(MSBuildProjectDirectory)', '$(IntermediateOutputPath)', 'IIDOptimizer')) + @(ReferencePathWithRefAssemblies->'--refs %(Identity)', ' ') + include the current dll, the folder to winrt.runtime, and the reference assemblies --> ---target +--target $(CsWinRTIIDOptimizerTargetAssembly) -$(GuidPatchTargetAssemblyReferences) +--outdir +$(IIDOptimizerInterimDir) +$(GuidPatchTargetAssemblyReferences) @@ -183,7 +186,7 @@ $(GuidPatchTargetAssemblyReferences) BeforeTargets="Link"> - + diff --git a/src/Perf/IIDOptimizer/GuidPatcher.cs b/src/Perf/IIDOptimizer/GuidPatcher.cs index 092804c35..54110a889 100644 --- a/src/Perf/IIDOptimizer/GuidPatcher.cs +++ b/src/Perf/IIDOptimizer/GuidPatcher.cs @@ -29,30 +29,10 @@ class GuidPatcher private readonly TypeDefinition guidImplementationDetailsType; private readonly TypeDefinition guidDataBlockType; private SignatureGenerator signatureGenerator; - - // OptimizerDir is the path our current process should use to write logs and patched DLLs to - public string OptimizerDir - { - get { return "obj\\IIDOptimizer"; } - } - - public GuidPatcher(string assemblyPath, IAssemblyResolver assemblyResolver, AssemblyDefinition winRTRuntime) + + public GuidPatcher(AssemblyDefinition winRTRuntime, AssemblyDefinition targetAssembly) { - var readerParameters = new ReaderParameters(ReadingMode.Deferred) - { - ReadWrite = true, - InMemory = true, - AssemblyResolver = assemblyResolver, - ThrowIfSymbolsAreNotMatching = false, - SymbolReaderProvider = new DefaultSymbolReaderProvider(false), - ApplyWindowsRuntimeProjections = false, - ReadSymbols = true - }; - - /* - * Initialize readonly fields - */ - assembly = AssemblyDefinition.ReadAssembly(assemblyPath, readerParameters); + assembly = targetAssembly; winRTRuntimeAssembly = winRTRuntime; diff --git a/src/Perf/IIDOptimizer/Program.cs b/src/Perf/IIDOptimizer/Program.cs index 29eb7f46e..a3742ed71 100644 --- a/src/Perf/IIDOptimizer/Program.cs +++ b/src/Perf/IIDOptimizer/Program.cs @@ -1,4 +1,5 @@ using Mono.Cecil; +using Mono.Cecil.Cil; using System; using System.IO; using System.CommandLine; @@ -6,6 +7,8 @@ using System.Threading.Tasks; using System.Collections.Generic; +using System.Linq; + namespace GuidPatch { class Program @@ -18,7 +21,16 @@ class Program argumentType: typeof(string), arity: ArgumentArity.ExactlyOne ); - + + static readonly Option _outputDir = + new Option + ( + alias: "--outputDirectory", + description: "The directory to save the patched .dll to.", + argumentType: typeof(string), + arity: ArgumentArity.ExactlyOne + ); + static readonly Option _references = new Option ( @@ -33,33 +45,50 @@ static async Task Main(string[] args) var rootCommand = new RootCommand { }; // friendlier option names _targetAssembly.AddAlias("--target"); + _outputDir.AddAlias("--outdir"); _references.AddAlias("--refs"); rootCommand.AddOption(_targetAssembly); + rootCommand.AddOption(_outputDir); rootCommand.AddOption(_references); - rootCommand.Handler = CommandHandler.Create>(GuidPatch); + rootCommand.Handler = CommandHandler.Create>(GuidPatch); await rootCommand.InvokeAsync(args); } - private static int GuidPatch(string targetAssembly, IEnumerable references) + private static int GuidPatch(string targetAssembly, string outputDirectory, IEnumerable references) { var resolver = new ReferenceAssemblyResolver(references); try { AssemblyDefinition winRTRuntimeAssembly = resolver.Resolve(new AssemblyNameReference("WinRT.Runtime", default)); - Directory.CreateDirectory("obj\\IIDOptimizer"); - - var guidPatcher = new GuidPatcher( - targetAssembly, - resolver, - winRTRuntimeAssembly); + var readerParameters = new ReaderParameters(ReadingMode.Deferred) + { + ReadWrite = true, + InMemory = true, + AssemblyResolver = resolver, + ThrowIfSymbolsAreNotMatching = false, + SymbolReaderProvider = new DefaultSymbolReaderProvider(false), + ApplyWindowsRuntimeProjections = false, + ReadSymbols = true + }; + + var targetAssemblyDefinition = AssemblyDefinition.ReadAssembly(targetAssembly, readerParameters); + + if (targetAssemblyDefinition.MainModule.Types.Any(typeDef => typeDef.Name == "")) + { + Console.WriteLine("Target assembly has already been patched. Exiting early as there is no work to do."); + return -2; + } + + var guidPatcher = new GuidPatcher(winRTRuntimeAssembly, targetAssemblyDefinition); int numPatches = guidPatcher.ProcessAssembly(); - guidPatcher.SaveAssembly(guidPatcher.OptimizerDir); + guidPatcher.SaveAssembly(outputDirectory); + Console.WriteLine($"Saved patched .dll to {outputDirectory}"); Console.WriteLine($"{numPatches} IID calculations/fetches patched"); return 0; } From f7ace89189ca44f94b68199c55aff2a0070e6b81 Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Sun, 18 Jul 2021 12:09:01 -0700 Subject: [PATCH 24/24] Feedback 2 --- nuget/Microsoft.Windows.CsWinRT.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nuget/Microsoft.Windows.CsWinRT.targets b/nuget/Microsoft.Windows.CsWinRT.targets index cc0645f3a..2cbff2808 100644 --- a/nuget/Microsoft.Windows.CsWinRT.targets +++ b/nuget/Microsoft.Windows.CsWinRT.targets @@ -186,7 +186,7 @@ $(GuidPatchTargetAssemblyReferences) BeforeTargets="Link"> - +