Kaynağa Gözat

Support explict size

sunnycase 6 yıl önce
ebeveyn
işleme
3a2dbb3a2a
2 değiştirilmiş dosya ile 43 ekleme ve 0 silme
  1. 8 0
      src/Natsu.Compiler/Program.cs
  2. 35 0
      src/Natsu.Compiler/TypeUtils.cs

+ 8 - 0
src/Natsu.Compiler/Program.cs

@@ -411,6 +411,8 @@ namespace Natsu.Compiler
             WriteVTableDeclare(writer, ident + 1, type);
             writer.WriteLine();
 
+            var hasSize = type.TypeDef.HasClassLayout && type.TypeDef.ClassLayout.ClassSize != 0;
+            string fieldSize = "0";
             foreach (var field in type.TypeDef.Fields)
             {
                 if (field.HasConstant && field.ElementType != ElementType.String)
@@ -419,8 +421,14 @@ namespace Natsu.Compiler
                     WriteField(writer, ident + 1, field);
                 else
                     hasStaticMember = true;
+
+                if (hasSize && !field.IsStatic)
+                    fieldSize += " + " + TypeUtils.GetTypeSize(field.FieldType.ElementType);
             }
 
+            if (hasSize)
+                writer.Ident(ident + 1).WriteLine($"uint8_t padding_[{type.TypeDef.ClassLayout.ClassSize} - ({fieldSize})];");
+
             writer.WriteLine();
 
             foreach (var method in type.TypeDef.Methods)

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

@@ -447,6 +447,41 @@ namespace Natsu.Compiler
             }
         }
 
+        public static string GetTypeSize(ElementType elementType)
+        {
+            switch (elementType)
+            {
+                case ElementType.Boolean:
+                case ElementType.I1:
+                case ElementType.U1:
+                    return "1";
+                case ElementType.Char:
+                case ElementType.I2:
+                case ElementType.U2:
+                    return "2";
+                case ElementType.I4:
+                case ElementType.U4:
+                case ElementType.R4:
+                    return "4";
+                case ElementType.I8:
+                case ElementType.U8:
+                case ElementType.R8:
+                    return "8";
+                case ElementType.String:
+                case ElementType.Ptr:
+                case ElementType.ByRef:
+                case ElementType.Class:
+                case ElementType.I:
+                case ElementType.U:
+                case ElementType.Object:
+                case ElementType.SZArray:
+                case ElementType.FnPtr:
+                    return "sizeof(intptr_t)";
+                default:
+                    throw new InvalidProgramException();
+            }
+        }
+
         public static string EscapeNamespaceName(string ns)
         {
             return ns;