sunnycase 6 年 前
コミット
9bff59cdda

+ 4 - 0
src/Native/main.cpp

@@ -10,6 +10,10 @@ void InitializeHeap() noexcept;
 
 int main()
 {
+    int32_t followCount = 0, resultCount = 0;
+#line 536 "D:\\Work\\Repository\\corert.git\\src\\System.Private.CoreLib\\src\\System\\Delegate.cs"
+    int32_t _35 = followCount; int32_t _36 = 1 + 1; resultCount = (int32_t)_36;
+
     InitializeHeap();
     Program::_s_Main();
 

+ 3 - 3
src/Natsu.Compiler/ILImporter.cs

@@ -1098,20 +1098,20 @@ namespace Natsu.Compiler
         public void Ldloc()
         {
             var local = Op.GetLocal(Method.Body.Variables.ToList());
-            Stack.Push(TypeUtils.GetStackType(local.Type), $"::natsu::stack_from(_l{local.Index})");
+            Stack.Push(TypeUtils.GetStackType(local.Type), $"::natsu::stack_from({TypeUtils.GetLocalName(local, Method)})");
         }
 
         public void Ldloca()
         {
             var local = Op.GetLocal(Method.Body.Variables.ToList());
-            Stack.Push(StackTypeCode.Ref, $"::natsu::ops::ref(_l{local.Index})");
+            Stack.Push(StackTypeCode.Ref, $"::natsu::ops::ref({TypeUtils.GetLocalName(local, Method)})");
         }
 
         public void Stloc()
         {
             var local = Op.GetLocal(Method.Body.Variables.ToList());
             var value = Stack.Pop();
-            Writer.Ident(Ident).WriteLine($"_l{local.Index} = {CastExpression(local.Type, value)};");
+            Writer.Ident(Ident).WriteLine($"{TypeUtils.GetLocalName(local, Method)} = {CastExpression(local.Type, value)};");
         }
 
         public void Br()

+ 1 - 0
src/Natsu.Compiler/Natsu.Compiler.csproj

@@ -7,6 +7,7 @@
 
   <ItemGroup>
     <PackageReference Include="dnlib" Version="3.2.0" />
+    <PackageReference Include="ICSharpCode.Decompiler" Version="5.0.2.5153" />
     <PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.2" />
   </ItemGroup>
 

+ 45 - 17
src/Natsu.Compiler/Program.cs

@@ -4,6 +4,7 @@ using System.IO;
 using System.Linq;
 using System.Reflection.Metadata;
 using System.Runtime.CompilerServices;
+using System.Security.Cryptography;
 using System.Text;
 using dnlib.DotNet;
 using dnlib.DotNet.Emit;
@@ -16,19 +17,19 @@ namespace Natsu.Compiler
         {
             @"..\..\..\..\..\out\bin\netcoreapp3.0\Chino.Kernel.dll",
             @"..\..\..\..\..\out\bin\netcoreapp3.0\Chino.Core.dll",
-            //@"..\..\..\..\..\out\bin\netcoreapp3.0\Chino.Chip.K210.dll",
+            @"..\..\..\..\..\out\bin\netcoreapp3.0\Chino.Chip.K210.dll",
             @"..\..\..\..\..\out\bin\netcoreapp3.0\Chino.Chip.Emulator.dll",
-            //@"..\..\..\..\..\out\bin\netcoreapp3.0\System.Private.CoreLib.dll",
-            //@"..\..\..\..\..\out\bin\netcoreapp3.0\System.Collections.dll",
-            //@"..\..\..\..\..\out\bin\netcoreapp3.0\System.Memory.dll",
+            @"..\..\..\..\..\out\bin\netcoreapp3.0\System.Private.CoreLib.dll",
+            @"..\..\..\..\..\out\bin\netcoreapp3.0\System.Collections.dll",
+            @"..\..\..\..\..\out\bin\netcoreapp3.0\System.Memory.dll",
             @"..\..\..\..\..\out\bin\netcoreapp3.0\System.Runtime.dll",
-            //@"..\..\..\..\..\out\bin\netcoreapp3.0\System.Runtime.Extensions.dll",
-            //@"..\..\..\..\..\out\bin\netcoreapp3.0\System.Diagnostics.Debug.dll",
-            //@"..\..\..\..\..\out\bin\netcoreapp3.0\System.Diagnostics.Process.dll",
-            //@"..\..\..\..\..\out\bin\netcoreapp3.0\System.Runtime.InteropServices.dll",
-            //@"..\..\..\..\..\out\bin\netcoreapp3.0\System.Threading.dll",
-            //@"..\..\..\..\..\out\bin\netcoreapp3.0\System.Threading.Thread.dll",
-            //Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), @".nuget\packages\bitfields\0.1.0\lib\netstandard1.0\BitFields.dll")
+            @"..\..\..\..\..\out\bin\netcoreapp3.0\System.Runtime.Extensions.dll",
+            @"..\..\..\..\..\out\bin\netcoreapp3.0\System.Diagnostics.Debug.dll",
+            @"..\..\..\..\..\out\bin\netcoreapp3.0\System.Diagnostics.Process.dll",
+            @"..\..\..\..\..\out\bin\netcoreapp3.0\System.Runtime.InteropServices.dll",
+            @"..\..\..\..\..\out\bin\netcoreapp3.0\System.Threading.dll",
+            @"..\..\..\..\..\out\bin\netcoreapp3.0\System.Threading.Thread.dll",
+            Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), @".nuget\packages\bitfields\0.1.0\lib\netstandard1.0\BitFields.dll")
         };
 
         static void Main(string[] args)
@@ -51,6 +52,7 @@ namespace Natsu.Compiler
         private readonly CorLibTypes _corLibTypes;
         private TypeDesc _szArrayType;
         private List<string> _userStrings = new List<string>();
+        private const string DigestHeader = "// Generated by NatsuCLR Compiler, digest: ";
 
         public Generator(ModuleDefMD module)
         {
@@ -60,6 +62,19 @@ namespace Natsu.Compiler
 
         public void Generate()
         {
+            var outputPath = Path.GetFullPath(@"..\..\..\..\Native\Generated");
+            Directory.CreateDirectory(outputPath);
+            string digest;
+
+            using (var sha256 = SHA256.Create())
+            {
+                digest = Convert.ToBase64String(sha256.ComputeHash(File.ReadAllBytes(_module.Location)));
+#if false
+                if (HasOutputUptodate(Path.Combine(outputPath, $"{_module.Assembly.Name}.h"), digest))
+                    return;
+#endif
+            }
+
             foreach (var type in _module.GetTypes())
             {
                 var typeDesc = new TypeDesc(type);
@@ -71,12 +86,9 @@ namespace Natsu.Compiler
 
             SortTypes();
 
-            var outputPath = Path.GetFullPath(@"..\..\..\..\Native\Generated");
-            Directory.CreateDirectory(outputPath);
-
             using (var writer = new StreamWriter(Path.Combine(outputPath, $"{_module.Assembly.Name}.h"), false, Encoding.UTF8))
             {
-                writer.WriteLine("// Generated by natsu clr compiler.");
+                writer.WriteLine(DigestHeader + digest);
                 writer.WriteLine("#pragma once");
                 if (_module.Assembly.Name == "System.Private.CoreLib")
                 {
@@ -115,7 +127,7 @@ namespace Natsu.Compiler
 
                 using (var writerSrc = new StreamWriter(Path.Combine(outputPath, $"{_module.Assembly.Name}.cpp"), false, Encoding.UTF8))
                 {
-                    writerSrc.WriteLine("// Generated by natsu clr compiler.");
+                    writer.WriteLine(DigestHeader + digest);
                     writerSrc.WriteLine($"#include \"{_module.Assembly.Name}.h\"");
                     writerSrc.WriteLine();
 
@@ -142,6 +154,22 @@ namespace Natsu.Compiler
             }
         }
 
+        private bool HasOutputUptodate(string file, string digest)
+        {
+            try
+            {
+                using (var sr = new StreamReader(file, Encoding.UTF8))
+                {
+                    var fileDigest = sr.ReadLine().Split(DigestHeader)[1];
+                    return fileDigest == digest;
+                }
+            }
+            catch (Exception)
+            {
+                return false;
+            }
+        }
+
         private void WriteAssemblyEmbeddedCode(AssemblyDef assembly, StreamWriter writer)
         {
             foreach (var att in assembly.CustomAttributes.FindAll("Natsu.AssemblyEmbeddedCodeAttribute"))
@@ -1071,7 +1099,7 @@ namespace Natsu.Compiler
 
         private void WriteLocal(Local local, TextWriter writer, int ident, MethodDef method)
         {
-            writer.Ident(ident).WriteLine($"{TypeUtils.EscapeVariableTypeName(local.Type)} _l{local.Index};");
+            writer.Ident(ident).WriteLine($"{TypeUtils.EscapeVariableTypeName(local.Type)} {TypeUtils.GetLocalName(local, method)};");
         }
 
         class TypeDesc

+ 15 - 0
src/Natsu.Compiler/TypeUtils.cs

@@ -5,6 +5,7 @@ using System.Linq;
 using System.Runtime.CompilerServices;
 using System.Text;
 using dnlib.DotNet;
+using dnlib.DotNet.Emit;
 
 namespace Natsu.Compiler
 {
@@ -857,5 +858,19 @@ namespace Natsu.Compiler
         {
             return type1 == type2 || type1 == type2.Scope;
         }
+
+        public static string GetLocalName(Local local, MethodDef method)
+        {
+            string localName = null;
+            if (method.Body.HasPdbMethod)
+            {
+                var scope = method.Body.PdbMethod.Scope;
+                var pdbLocal = scope.Variables.FirstOrDefault(x => x.Index == local.Index);
+                if (pdbLocal != null)
+                    localName = pdbLocal.Name;
+            }
+
+            return localName ?? $"_l{local.Index}";
+        }
     }
 }