Emit fixed buffers using standard api only
authorMarek Safar <marek.safar@gmail.com>
Mon, 22 Nov 2010 16:49:47 +0000 (16:49 +0000)
committerMarek Safar <marek.safar@gmail.com>
Mon, 22 Nov 2010 16:49:47 +0000 (16:49 +0000)
mcs/mcs/assembly.cs
mcs/mcs/attribute.cs
mcs/mcs/class.cs
mcs/mcs/field.cs
mcs/tests/gtest-fixedbuffer-08.cs [new file with mode: 0644]
mcs/tests/ver-il-dmcs.xml
mcs/tests/ver-il-gmcs.xml

index 5d91ea214502530d75c261bc632cc812af4b991c..a9236a73ac009b851b6cec7f42e642bb4bfcae10 100644 (file)
@@ -670,7 +670,7 @@ namespace Mono.CSharp
 
                        Attribute a = module.ResolveAssemblyAttribute (Compiler.PredefinedAttributes.RuntimeCompatibility);
                        if (a != null) {
-                               var val = a.GetPropertyValue ("WrapNonExceptionThrows") as BoolConstant;
+                               var val = a.GetNamedValue ("WrapNonExceptionThrows") as BoolConstant;
                                if (val != null)
                                        wrap_non_exception_throws = val.Value;
                        }
index fde8c287394090615d7c01475df962e04a4f5301..1ba4d25296fa4d1a90d2167c8f1b5f9bcf2471a4 100644 (file)
@@ -584,11 +584,11 @@ namespace Mono.CSharp {
 
                        AttributeUsageAttribute usage_attribute = new AttributeUsageAttribute ((AttributeTargets)((Constant) PosArguments [0].Expr).GetValue ());
 
-                       var field = GetPropertyValue ("AllowMultiple") as BoolConstant;
+                       var field = GetNamedValue ("AllowMultiple") as BoolConstant;
                        if (field != null)
                                usage_attribute.AllowMultiple = field.Value;
 
-                       field = GetPropertyValue ("Inherited") as BoolConstant;
+                       field = GetNamedValue ("Inherited") as BoolConstant;
                        if (field != null)
                                usage_attribute.Inherited = field.Value;
 
@@ -858,7 +858,7 @@ namespace Mono.CSharp {
                        ps.AddPermission (perm);
                }
 
-               public Constant GetPropertyValue (string name)
+               public Constant GetNamedValue (string name)
                {
                        if (named_values == null)
                                return null;
@@ -1426,6 +1426,11 @@ namespace Mono.CSharp {
                        Stream.Write (value);
                }
 
+               public void Encode (short value)
+               {
+                       Stream.Write (value);
+               }
+
                public void Encode (int value)
                {
                        Stream.Write (value);
@@ -1522,6 +1527,27 @@ namespace Mono.CSharp {
                        value.EncodeAttributeValue (null, this, field.MemberType);
                }
 
+               public void EncodeNamedArguments<T> (T[] members, Constant[] values) where T : MemberSpec, IInterfaceMemberSpec
+               {
+                       Stream.Write ((ushort) members.Length);
+
+                       for (int i = 0; i < members.Length; ++i)
+                       {
+                               var member = members[i];
+
+                               if (member.Kind == MemberKind.Field)
+                                       Stream.Write ((byte) 0x53);
+                               else if (member.Kind == MemberKind.Property)
+                                       Stream.Write ((byte) 0x54);
+                               else
+                                       throw new NotImplementedException (member.Kind.ToString ());
+
+                               Encode (member.MemberType);
+                               Encode (member.Name);
+                               values [i].EncodeAttributeValue (null, this, member.MemberType);
+                       }
+               }
+
                public void EncodeEmptyNamedArguments ()
                {
                        Stream.Write ((ushort) 0);
index 9b48935451f03432ba6165ccd06c01bce2047c3e..7d6413a7fd41a639423989e8362319b8b71f3eab 100644 (file)
@@ -2627,13 +2627,19 @@ namespace Mono.CSharp {
                        //
                        // When struct constains fixed fixed and struct layout has explicitly
                        // set CharSet, its value has to be propagated to compiler generated
-                       // fixed field types
+                       // fixed types
                        //
-                       if (a.Type == pa.StructLayout && Fields != null && a.HasField ("CharSet")) {
+                       if (a.Type == pa.StructLayout && Fields != null) {
+                               var value = a.GetNamedValue ("CharSet");
+                               if (value == null)
+                                       return;
+
                                for (int i = 0; i < Fields.Count; ++i) {
                                        FixedField ff = Fields [i] as FixedField;
-                                       if (ff != null)
-                                               ff.SetCharSet (TypeBuilder.Attributes);
+                                       if (ff == null)
+                                               continue;
+
+                                       ff.CharSet = (CharSet) System.Enum.Parse (typeof (CharSet), value.GetValue ().ToString ());
                                }
                        }
                }
index 897c94c481dc9bfbdb1d3e392c9c1138972f9ee4..661a2a2f0ced29a661810431687f89efb7005811 100644 (file)
@@ -354,6 +354,17 @@ namespace Mono.CSharp
                {
                }
 
+               #region Properties
+
+               //
+               // Explicit struct layout set be parent
+               //
+               public CharSet? CharSet {
+                       get; set;
+               }               
+
+               #endregion
+
                public override Constant ConvertInitializer (ResolveContext rc, Constant expr)
                {
                        return expr.ImplicitConversionRequired (rc, TypeManager.int32_type, Location);
@@ -448,14 +459,25 @@ namespace Mono.CSharp
                        if (pa.Constructor == null && !pa.ResolveConstructor (Location, TypeManager.short_type))
                                return;
 
-                       var field = pa.GetField ("Size", TypeManager.int32_type, Location);
-                       if (field != null) {
-                               encoder = new AttributeEncoder (false);
-                               encoder.Encode ((short)LayoutKind.Sequential);
-                               encoder.EncodeNamedFieldArgument (field, new IntConstant (buffer_size, Location));
+                       var interop_charset = TypeManager.CoreLookupType (Compiler, "System.Runtime.InteropServices", "CharSet", MemberKind.Enum, true);
+                       if (interop_charset == null)
+                               return;
 
-                               pa.EmitAttribute (fixed_buffer_type, encoder);
-                       }
+                       var field_size = pa.GetField ("Size", TypeManager.int32_type, Location);
+                       var field_charset = pa.GetField ("CharSet", interop_charset, Location);
+                       if (field_size == null || field_charset == null)
+                               return;
+
+                       var char_set = CharSet ?? Module.DefaultCharSet;
+
+                       encoder = new AttributeEncoder (false);
+                       encoder.Encode ((short)LayoutKind.Sequential);
+                       encoder.EncodeNamedArguments (
+                               new [] { field_size, field_charset },
+                               new Constant [] { new IntConstant (buffer_size, Location), new IntConstant ((int) char_set, Location) }
+                       );
+
+                       pa.EmitAttribute (fixed_buffer_type, encoder);
 
                        //
                        // Don't emit FixedBufferAttribute attribute for private types
@@ -474,27 +496,6 @@ namespace Mono.CSharp
 
                        pa.EmitAttribute (FieldBuilder, encoder);
                }
-
-               public void SetCharSet (TypeAttributes ta)
-               {
-                       TypeAttributes cta = fixed_buffer_type.Attributes;
-                       if ((cta & TypeAttributes.UnicodeClass) != (ta & TypeAttributes.UnicodeClass))
-                               SetTypeBuilderCharSet ((cta & ~TypeAttributes.AutoClass) | TypeAttributes.UnicodeClass);
-                       else if ((cta & TypeAttributes.AutoClass) != (ta & TypeAttributes.AutoClass))
-                               SetTypeBuilderCharSet ((cta & ~TypeAttributes.UnicodeClass) | TypeAttributes.AutoClass);
-                       else if (cta == 0 && ta != 0)
-                               SetTypeBuilderCharSet (cta & ~(TypeAttributes.UnicodeClass | TypeAttributes.AutoClass));
-               }
-
-               void SetTypeBuilderCharSet (TypeAttributes ta)
-               {
-                       MethodInfo mi = typeof (TypeBuilder).GetMethod ("SetCharSet", BindingFlags.Instance | BindingFlags.NonPublic);
-                       if (mi == null) {
-                               Report.RuntimeMissingSupport (Location, "TypeBuilder::SetCharSet");
-                       } else {
-                               mi.Invoke (fixed_buffer_type, new object [] { ta });
-                       }
-               }
        }
 
        class FixedFieldSpec : FieldSpec
diff --git a/mcs/tests/gtest-fixedbuffer-08.cs b/mcs/tests/gtest-fixedbuffer-08.cs
new file mode 100644 (file)
index 0000000..cad4f3b
--- /dev/null
@@ -0,0 +1,46 @@
+// Compiler options: -unsafe
+
+using System;
+using System.Runtime.InteropServices;
+
+[StructLayout (LayoutKind.Auto, CharSet = CharSet.Auto)]
+struct S
+{
+       public unsafe fixed byte o[6];
+}
+
+class A
+{
+       public static int Main ()
+       {
+               Type t = typeof (S);
+               var sa = t.StructLayoutAttribute;
+               if (sa.Value != LayoutKind.Auto)
+                       return 1;
+
+               if (sa.CharSet != CharSet.Auto)
+                       return 2;
+
+               if (sa.Pack != 8)
+                       return 3;
+
+               if (sa.Size != 0)
+                       return 4;
+
+               t = t.GetNestedTypes ()[0];
+               sa = t.StructLayoutAttribute;
+               if (sa.Value != LayoutKind.Sequential)
+                       return 11;
+
+               if (sa.CharSet != CharSet.Auto)
+                       return 12;
+
+               if (sa.Pack != 8)
+                       return 13;
+
+               if (sa.Size != 6)
+                       return 14;
+
+               return 0;
+       }
+}
index b68e593be233868e39839b6abdbf09085b29e763..f1d6ec4fd1658dab2729b0d0d2cd974c192da5e0 100644 (file)
       </method>
     </type>
   </test>
-  <test name="gtest-166.cs">
-    <type name="C">
-      <method name="Void .ctor()">
-        <size>7</size>
-      </method>
-      <method name="Int32 Test()">
-        <size>323</size>
-      </method>
-      <method name="Int32 Main()">
-        <size>6</size>
-      </method>
-    </type>
-    <type name="TestNew">
-      <method name="Void SetTest()">
-        <size>20</size>
-      </method>
-    </type>
-  </test>
   <test name="gtest-167.cs">
     <type name="TestAttribute">
       <method name="Void .ctor()">
       </method>
     </type>
   </test>
-  <test name="gtest-353.cs">
-    <type name="Bug.RedSkyTimeCode">
-      <method name="Void .ctor()">
-        <size>7</size>
-      </method>
-      <method name="Void CopyTo(Bug.xxx*)">
-        <size>99</size>
-      </method>
-      <method name="Void Main()">
-        <size>1</size>
-      </method>
-      <method name="Void Convert(Bug.xxx*, UInt64*)">
-        <size>93</size>
-      </method>
-    </type>
-  </test>
-  <test name="gtest-354.cs">
-    <type name="M">
-      <method name="Void .ctor()">
-        <size>7</size>
-      </method>
-      <method name="Void Main()">
-        <size>1</size>
-      </method>
-    </type>
-  </test>
   <test name="gtest-355.cs">
     <type name="A">
       <method name="Void .ctor()">
       </method>
     </type>
   </test>
-  <test name="gtest-374.cs">
-    <type name="aClass">
-      <method name="Void .ctor()">
-        <size>7</size>
-      </method>
-      <method name="Void Main(System.String[])">
-        <size>14</size>
-      </method>
-    </type>
-  </test>
   <test name="gtest-375.cs">
     <type name="X">
       <method name="Void .ctor()">
       </method>
     </type>
   </test>
-  <test name="gtest-415.cs">
-    <type name="S2">
-      <method name="Void Test()">
-        <size>39</size>
-      </method>
-      <method name="Void Main()">
-        <size>16</size>
-      </method>
-    </type>
-  </test>
-  <test name="gtest-416.cs">
-    <type name="Bug.Demo">
-      <method name="Boolean Fixed()">
-        <size>14</size>
-      </method>
-      <method name="Boolean Foo(System.Int32[])">
-        <size>43</size>
-      </method>
-      <method name="Int32 Main()">
-        <size>65</size>
-      </method>
-    </type>
-  </test>
-  <test name="gtest-417.cs">
-    <type name="C">
-      <method name="Void .ctor()">
-        <size>7</size>
-      </method>
-      <method name="Void Goo()">
-        <size>11</size>
-      </method>
-      <method name="Void Main()">
-        <size>1</size>
-      </method>
-    </type>
-  </test>
   <test name="gtest-418.cs">
     <type name="N.Nested">
       <method name="Void .ctor()">
       </method>
     </type>
   </test>
+  <test name="gtest-fixedbuffer-01.cs">
+    <type name="TestNew">
+      <method name="Void SetTest()">
+        <size>20</size>
+      </method>
+    </type>
+    <type name="C">
+      <method name="Int32 Test()">
+        <size>323</size>
+      </method>
+      <method name="Int32 Main()">
+        <size>6</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="gtest-fixedbuffer-02.cs">
+    <type name="M">
+      <method name="Void Main()">
+        <size>1</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="gtest-fixedbuffer-03.cs">
+    <type name="Bug.RedSkyTimeCode">
+      <method name="Void CopyTo(Bug.xxx*)">
+        <size>99</size>
+      </method>
+      <method name="Void Convert(Bug.xxx*, UInt64*)">
+        <size>93</size>
+      </method>
+      <method name="Void Main()">
+        <size>1</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="gtest-fixedbuffer-04.cs">
+    <type name="aClass">
+      <method name="Void Main(System.String[])">
+        <size>14</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="gtest-fixedbuffer-05.cs">
+    <type name="S2">
+      <method name="Void Test()">
+        <size>39</size>
+      </method>
+      <method name="Void Main()">
+        <size>16</size>
+      </method>
+    </type>
+  </test>
+  <test name="gtest-fixedbuffer-06.cs">
+    <type name="Bug.Demo">
+      <method name="Boolean Fixed()">
+        <size>14</size>
+      </method>
+      <method name="Boolean Foo(System.Int32[])">
+        <size>43</size>
+      </method>
+      <method name="Int32 Main()">
+        <size>65</size>
+      </method>
+    </type>
+  </test>
+  <test name="gtest-fixedbuffer-07.cs">
+    <type name="C">
+      <method name="Void Goo()">
+        <size>11</size>
+      </method>
+      <method name="Void Main()">
+        <size>1</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="gtest-fixedbuffer-08.cs">
+    <type name="A">
+      <method name="Int32 Main()">
+        <size>150</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-friend-01.cs">
     <type name="Test">
       <method name="Void .ctor()">
index 62bf29ea36a0b261e29f78558bfe76cd413b644e..39cbff07c308af16115bc5c64790048421fd2c81 100644 (file)
       </method>
     </type>
   </test>
-  <test name="gtest-166.cs">
-    <type name="C">
-      <method name="Void .ctor()">
-        <size>7</size>
-      </method>
-      <method name="Int32 Test()">
-        <size>323</size>
-      </method>
-      <method name="Int32 Main()">
-        <size>6</size>
-      </method>
-    </type>
-    <type name="TestNew">
-      <method name="Void SetTest()">
-        <size>20</size>
-      </method>
-    </type>
-  </test>
   <test name="gtest-167.cs">
     <type name="TestAttribute">
       <method name="Void .ctor()">
       </method>
     </type>
   </test>
-  <test name="gtest-353.cs">
-    <type name="Bug.RedSkyTimeCode">
-      <method name="Void .ctor()">
-        <size>7</size>
-      </method>
-      <method name="Void CopyTo(Bug.xxx*)">
-        <size>99</size>
-      </method>
-      <method name="Void Main()">
-        <size>1</size>
-      </method>
-      <method name="Void Convert(Bug.xxx*, UInt64*)">
-        <size>93</size>
-      </method>
-    </type>
-  </test>
-  <test name="gtest-354.cs">
-    <type name="M">
-      <method name="Void .ctor()">
-        <size>7</size>
-      </method>
-      <method name="Void Main()">
-        <size>1</size>
-      </method>
-    </type>
-  </test>
   <test name="gtest-355.cs">
     <type name="A">
       <method name="Void .ctor()">
       </method>
     </type>
   </test>
-  <test name="gtest-374.cs">
-    <type name="aClass">
-      <method name="Void .ctor()">
-        <size>7</size>
-      </method>
-      <method name="Void Main(System.String[])">
-        <size>14</size>
-      </method>
-    </type>
-  </test>
   <test name="gtest-375.cs">
     <type name="X">
       <method name="Void .ctor()">
       </method>
     </type>
   </test>
-  <test name="gtest-415.cs">
-    <type name="S2">
-      <method name="Void Test()">
-        <size>39</size>
-      </method>
-      <method name="Void Main()">
-        <size>16</size>
-      </method>
-    </type>
-  </test>
-  <test name="gtest-416.cs">
-    <type name="Bug.Demo">
-      <method name="Boolean Fixed()">
-        <size>14</size>
-      </method>
-      <method name="Boolean Foo(System.Int32[])">
-        <size>43</size>
-      </method>
-      <method name="Int32 Main()">
-        <size>65</size>
-      </method>
-    </type>
-  </test>
-  <test name="gtest-417.cs">
-    <type name="C">
-      <method name="Void .ctor()">
-        <size>7</size>
-      </method>
-      <method name="Void Goo()">
-        <size>11</size>
-      </method>
-      <method name="Void Main()">
-        <size>1</size>
-      </method>
-    </type>
-  </test>
   <test name="gtest-418.cs">
     <type name="N.Nested">
       <method name="Void .ctor()">
       </method>
     </type>
   </test>
+  <test name="gtest-fixedbuffer-01.cs">
+    <type name="TestNew">
+      <method name="Void SetTest()">
+        <size>20</size>
+      </method>
+    </type>
+    <type name="C">
+      <method name="Int32 Test()">
+        <size>323</size>
+      </method>
+      <method name="Int32 Main()">
+        <size>6</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="gtest-fixedbuffer-02.cs">
+    <type name="M">
+      <method name="Void Main()">
+        <size>1</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="gtest-fixedbuffer-03.cs">
+    <type name="Bug.RedSkyTimeCode">
+      <method name="Void CopyTo(Bug.xxx*)">
+        <size>99</size>
+      </method>
+      <method name="Void Convert(Bug.xxx*, UInt64*)">
+        <size>93</size>
+      </method>
+      <method name="Void Main()">
+        <size>1</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="gtest-fixedbuffer-04.cs">
+    <type name="aClass">
+      <method name="Void Main(System.String[])">
+        <size>14</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="gtest-fixedbuffer-05.cs">
+    <type name="S2">
+      <method name="Void Test()">
+        <size>39</size>
+      </method>
+      <method name="Void Main()">
+        <size>16</size>
+      </method>
+    </type>
+  </test>
+  <test name="gtest-fixedbuffer-06.cs">
+    <type name="Bug.Demo">
+      <method name="Boolean Fixed()">
+        <size>14</size>
+      </method>
+      <method name="Boolean Foo(System.Int32[])">
+        <size>43</size>
+      </method>
+      <method name="Int32 Main()">
+        <size>65</size>
+      </method>
+    </type>
+  </test>
+  <test name="gtest-fixedbuffer-07.cs">
+    <type name="C">
+      <method name="Void Goo()">
+        <size>11</size>
+      </method>
+      <method name="Void Main()">
+        <size>1</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="gtest-fixedbuffer-08.cs">
+    <type name="A">
+      <method name="Int32 Main()">
+        <size>150</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-friend-01.cs">
     <type name="Test">
       <method name="Void .ctor()">