diff --git a/source/MetadataProcessor.Console/Program.cs b/source/MetadataProcessor.Console/Program.cs index 654f73a1..3ac8b7d2 100644 --- a/source/MetadataProcessor.Console/Program.cs +++ b/source/MetadataProcessor.Console/Program.cs @@ -63,12 +63,15 @@ public void Compile( _assemblyBuilder = new nanoAssemblyBuilder(_assemblyDefinition, _classNamesToExclude, VerboseMinimize, isCoreLibrary); - using (var stream = File.Open(fileName, FileMode.Create, FileAccess.ReadWrite)) + using (var stream = File.Open(Path.ChangeExtension(fileName, "tmp"), FileMode.Create, FileAccess.ReadWrite)) using (var writer = new BinaryWriter(stream)) { _assemblyBuilder.Write(GetBinaryWriter(writer)); } + // OK to delete tmp PE file + File.Delete(Path.ChangeExtension(fileName, "tmp")); + if (Verbose) System.Console.WriteLine("Minimizing assembly..."); _assemblyBuilder.Minimize(); diff --git a/source/MetadataProcessor.Core/Tables/nanoAssemblyReferenceTable.cs b/source/MetadataProcessor.Core/Tables/nanoAssemblyReferenceTable.cs index 285231c4..d4e714ae 100644 --- a/source/MetadataProcessor.Core/Tables/nanoAssemblyReferenceTable.cs +++ b/source/MetadataProcessor.Core/Tables/nanoAssemblyReferenceTable.cs @@ -55,6 +55,11 @@ protected override void WriteSingleItem( nanoBinaryWriter writer, AssemblyNameReference item) { + if (!_context.MinimizeComplete) + { + return; + } + WriteStringReference(writer, item.Name); writer.WriteUInt16(0); // padding diff --git a/source/MetadataProcessor.Core/Tables/nanoByteCodeTable.cs b/source/MetadataProcessor.Core/Tables/nanoByteCodeTable.cs index a613be13..18054b1c 100644 --- a/source/MetadataProcessor.Core/Tables/nanoByteCodeTable.cs +++ b/source/MetadataProcessor.Core/Tables/nanoByteCodeTable.cs @@ -24,13 +24,13 @@ public sealed class nanoByteCodeTable : InanoTable private readonly IList _methods = new List(); /// - /// Maps method full names to method RVAs (offsets in resutling table). + /// Maps method full names to method RVAs (offsets in resulting table). /// private readonly IDictionary _rvasByMethodNames = new Dictionary(StringComparer.Ordinal); /// - /// Temprorary string table for code generators used duing initial load. + /// Temporary string table for code generators used during initial load. /// private readonly nanoStringTable _fakeStringTable = new nanoStringTable(); @@ -57,12 +57,12 @@ public nanoByteCodeTable( } /// - /// Next method identifier. Used for reproducing strange original MetadataProcessor behavior. + /// Next method identifier. Used for reproducing strange original MetadataProcessor behaviour. /// public ushort NextMethodId { get { return (ushort)_methods.Count; } } /// - /// Temprorary string table for code generators used duing initial load. + /// Temporary string table for code generators used duing initial load. /// public nanoStringTable FakeStringTable { get { return _fakeStringTable; } } diff --git a/source/MetadataProcessor.Core/Tables/nanoFieldDefinitionTable.cs b/source/MetadataProcessor.Core/Tables/nanoFieldDefinitionTable.cs index ce8ae723..d17041c6 100644 --- a/source/MetadataProcessor.Core/Tables/nanoFieldDefinitionTable.cs +++ b/source/MetadataProcessor.Core/Tables/nanoFieldDefinitionTable.cs @@ -66,6 +66,11 @@ protected override void WriteSingleItem( nanoBinaryWriter writer, FieldDefinition item) { + if (!_context.MinimizeComplete) + { + return; + } + WriteStringReference(writer, item.Name); writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(item)); diff --git a/source/MetadataProcessor.Core/Tables/nanoFieldReferenceTable.cs b/source/MetadataProcessor.Core/Tables/nanoFieldReferenceTable.cs index 909a2e24..df6b5650 100644 --- a/source/MetadataProcessor.Core/Tables/nanoFieldReferenceTable.cs +++ b/source/MetadataProcessor.Core/Tables/nanoFieldReferenceTable.cs @@ -68,6 +68,11 @@ protected override void WriteSingleItem( nanoBinaryWriter writer, FieldReference item) { + if (!_context.MinimizeComplete) + { + return; + } + ushort referenceId; _context.TypeReferencesTable.TryGetTypeReferenceId(item.DeclaringType, out referenceId); diff --git a/source/MetadataProcessor.Core/Tables/nanoMethodDefinitionTable.cs b/source/MetadataProcessor.Core/Tables/nanoMethodDefinitionTable.cs index 24a7bbca..1d5cbd9d 100644 --- a/source/MetadataProcessor.Core/Tables/nanoMethodDefinitionTable.cs +++ b/source/MetadataProcessor.Core/Tables/nanoMethodDefinitionTable.cs @@ -1,6 +1,6 @@ +using Mono.Cecil; using System; using System.Collections.Generic; -using Mono.Cecil; namespace nanoFramework.Tools.MetadataProcessor { @@ -62,6 +62,11 @@ protected override void WriteSingleItem( nanoBinaryWriter writer, MethodDefinition item) { + if (!_context.MinimizeComplete) + { + return; + } + WriteStringReference(writer, item.Name); writer.WriteUInt16(_context.ByteCodeTable.GetMethodRva(item)); diff --git a/source/MetadataProcessor.Core/Tables/nanoMethodReferenceTable.cs b/source/MetadataProcessor.Core/Tables/nanoMethodReferenceTable.cs index 5e14bb3f..47f16d68 100644 --- a/source/MetadataProcessor.Core/Tables/nanoMethodReferenceTable.cs +++ b/source/MetadataProcessor.Core/Tables/nanoMethodReferenceTable.cs @@ -68,6 +68,11 @@ protected override void WriteSingleItem( nanoBinaryWriter writer, MethodReference item) { + if (!_context.MinimizeComplete) + { + return; + } + ushort referenceId; _context.TypeReferencesTable.TryGetTypeReferenceId(item.DeclaringType, out referenceId); diff --git a/source/MetadataProcessor.Core/Tables/nanoTablesContext.cs b/source/MetadataProcessor.Core/Tables/nanoTablesContext.cs index 88a6295a..1f4e1dc3 100644 --- a/source/MetadataProcessor.Core/Tables/nanoTablesContext.cs +++ b/source/MetadataProcessor.Core/Tables/nanoTablesContext.cs @@ -241,6 +241,7 @@ public ushort GetMethodReferenceId( public nanoResourceFileTable ResourceFileTable { get; private set; } public static List ClassNamesToExclude { get; private set; } + public bool MinimizeComplete { get; internal set; } = false; private IEnumerable> GetAttributes( IEnumerable types, diff --git a/source/MetadataProcessor.Core/Tables/nanoTypeDefinitionTable.cs b/source/MetadataProcessor.Core/Tables/nanoTypeDefinitionTable.cs index 1d498d69..2432319d 100644 --- a/source/MetadataProcessor.Core/Tables/nanoTypeDefinitionTable.cs +++ b/source/MetadataProcessor.Core/Tables/nanoTypeDefinitionTable.cs @@ -110,34 +110,38 @@ protected override void WriteSingleItem( { WriteClassFields(fieldsList, writer.GetMemoryBasedClone(stream)); - if (item.DeclaringType == null) + if (_context.MinimizeComplete) { - foreach (var method in item.Methods) - { - var offsets = CodeWriter - .PreProcessMethod(method, _context.ByteCodeTable.FakeStringTable) - .ToList(); - _byteCodeOffsets.Add(method.MetadataToken.ToUInt32(), offsets); + if (item.DeclaringType == null) + { + foreach (var method in item.Methods) + { + var offsets = CodeWriter + .PreProcessMethod(method, _context.ByteCodeTable.FakeStringTable) + .ToList(); + + _byteCodeOffsets.Add(method.MetadataToken.ToUInt32(), offsets); + } } - } - foreach (var nestedType in item.NestedTypes) - { - foreach (var method in nestedType.Methods) + foreach (var nestedType in item.NestedTypes) { - var offsets = CodeWriter - .PreProcessMethod(method, _context.ByteCodeTable.FakeStringTable) - .ToList(); - - _byteCodeOffsets.Add(method.MetadataToken.ToUInt32(), offsets); + foreach (var method in nestedType.Methods) + { + var offsets = CodeWriter + .PreProcessMethod(method, _context.ByteCodeTable.FakeStringTable) + .ToList(); + + _byteCodeOffsets.Add(method.MetadataToken.ToUInt32(), offsets); + } } - } - WriteMethodBodies(item.Methods, item.Interfaces, writer); + WriteMethodBodies(item.Methods, item.Interfaces, writer); - _context.SignaturesTable.WriteDataType(item, writer, false, true, true); + _context.SignaturesTable.WriteDataType(item, writer, false, true, true); - writer.WriteBytes(stream.ToArray()); + writer.WriteBytes(stream.ToArray()); + } } writer.WriteUInt16((ushort)GetFlags(item)); // flags diff --git a/source/MetadataProcessor.Core/Utility/nanoPdbxFileWriter.cs b/source/MetadataProcessor.Core/Utility/nanoPdbxFileWriter.cs index 666828e5..56ac47a2 100644 --- a/source/MetadataProcessor.Core/Utility/nanoPdbxFileWriter.cs +++ b/source/MetadataProcessor.Core/Utility/nanoPdbxFileWriter.cs @@ -7,6 +7,7 @@ using Mono.Cecil; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Globalization; using System.Linq; using System.Xml; @@ -75,13 +76,27 @@ private void WriteClassInfo( writer.WriteElementString("HasByteCode", "false"); } writer.WriteStartElement("ILMap"); + + // sanity check vars + uint prevItem1 = 0; + uint prevItem2 = 0; + foreach (var offset in _context.TypeDefinitionTable.GetByteCodeOffsets(tuple.Item1)) { + if (prevItem1 > 0) + { + // 1st pass, load prevs with current values + Debug.Assert(prevItem1 < offset.Item1); + Debug.Assert(prevItem2 < offset.Item2); + } writer.WriteStartElement("IL"); writer.WriteElementString("CLR", "0x" + offset.Item1.ToString("X8", CultureInfo.InvariantCulture)); writer.WriteElementString("nanoCLR", "0x" + offset.Item2.ToString("X8", CultureInfo.InvariantCulture)); + prevItem1 = offset.Item1; + prevItem2 = offset.Item2; + writer.WriteEndElement(); } writer.WriteEndElement(); diff --git a/source/MetadataProcessor.Core/nanoAssemblyBuilder.cs b/source/MetadataProcessor.Core/nanoAssemblyBuilder.cs index 650bca3e..13e308fe 100644 --- a/source/MetadataProcessor.Core/nanoAssemblyBuilder.cs +++ b/source/MetadataProcessor.Core/nanoAssemblyBuilder.cs @@ -219,6 +219,9 @@ public void Minimize() interfacesToRemove.Select(i => c.Interfaces.Remove(i)).ToList(); } + + // flag minimize completed + _tablesContext.MinimizeComplete = true; } private void ShowDependencies(MetadataToken token, HashSet set, HashSet setTmp)