Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Kyte <alexmkyte@gmail.com>2017-11-28 18:44:38 +0300
committerLudovic Henry <luhenry@microsoft.com>2017-11-28 18:44:38 +0300
commit0927d51418c20694046b25f84989b97eda0b6ad6 (patch)
treefb0338e5c615741a1fd4a3b08c3e516627d66ddf /mcs/class/corlib
parentb3fad3f0f899d3f28becf3f20843de8b84c62d98 (diff)
[runtime] Implement a few ModuleBuilder getters (#5787)
* [runtime] Implement a few broken getters on ModuleBuilder * [runtime] Implement ModuleBuilder.GetCustomAttributes * [runtime] Test GetMethods, GetCustomAttributes, and GetFields for ModuleBuilder * [runtime] Specify and test use of typebuilders with Custom Attributes + add more tests
Diffstat (limited to 'mcs/class/corlib')
-rw-r--r--mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs26
-rw-r--r--mcs/class/corlib/System.Reflection.Emit/ModuleBuilder.cs35
-rw-r--r--mcs/class/corlib/Test/System.Reflection.Emit/ModuleBuilderTest.cs205
3 files changed, 258 insertions, 8 deletions
diff --git a/mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs b/mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs
index 0bb724ad8c4..a0f11bd20cd 100644
--- a/mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs
+++ b/mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs
@@ -46,6 +46,11 @@ namespace System.Reflection.Emit {
public class CustomAttributeBuilder : _CustomAttributeBuilder {
ConstructorInfo ctor;
byte[] data;
+ object [] args;
+ PropertyInfo [] namedProperties;
+ object [] propertyValues;
+ FieldInfo [] namedFields;
+ object [] fieldValues;
internal ConstructorInfo Ctor {
get {return ctor;}
@@ -57,7 +62,20 @@ namespace System.Reflection.Emit {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static extern byte[] GetBlob(Assembly asmb, ConstructorInfo con, object[] constructorArgs, PropertyInfo[] namedProperties, object[] propertyValues, FieldInfo[] namedFields, object[] fieldValues);
-
+
+ internal object Invoke ()
+ {
+ object result = ctor.Invoke (args);
+
+ for (int i=0; i < namedFields.Length; i++)
+ namedFields [i].SetValue (result, fieldValues [i]);
+
+ for (int i=0; i < namedProperties.Length; i++)
+ namedProperties [i].SetValue (result, propertyValues [i]);
+
+ return result;
+ }
+
internal CustomAttributeBuilder( ConstructorInfo con, byte[] binaryAttribute) {
if (con == null)
throw new ArgumentNullException ("con");
@@ -140,6 +158,12 @@ namespace System.Reflection.Emit {
FieldInfo [] namedFields, object [] fieldValues)
{
ctor = con;
+ args = constructorArgs;
+ this.namedProperties = namedProperties;
+ this.propertyValues = propertyValues;
+ this.namedFields = namedFields;
+ this.fieldValues = fieldValues;
+
if (con == null)
throw new ArgumentNullException ("con");
if (constructorArgs == null)
diff --git a/mcs/class/corlib/System.Reflection.Emit/ModuleBuilder.cs b/mcs/class/corlib/System.Reflection.Emit/ModuleBuilder.cs
index f629f8a3861..8744b4a4581 100644
--- a/mcs/class/corlib/System.Reflection.Emit/ModuleBuilder.cs
+++ b/mcs/class/corlib/System.Reflection.Emit/ModuleBuilder.cs
@@ -1169,32 +1169,55 @@ namespace System.Reflection.Emit {
public override object[] GetCustomAttributes (bool inherit)
{
- return base.GetCustomAttributes (inherit);
+ return GetCustomAttributes (null, inherit);
}
public override object[] GetCustomAttributes (Type attributeType, bool inherit)
{
- return base.GetCustomAttributes (attributeType, inherit);
+ if (cattrs == null || cattrs.Length == 0)
+ return Array.Empty<object> ();
+
+ if (attributeType is TypeBuilder)
+ throw new InvalidOperationException ("First argument to GetCustomAttributes can't be a TypeBuilder");
+
+ List<object> results = new List<object> ();
+ for (int i=0; i < cattrs.Length; i++) {
+ Type t = cattrs [i].Ctor.GetType ();
+
+ if (t is TypeBuilder)
+ throw new InvalidOperationException ("Can't construct custom attribute for TypeBuilder type");
+
+ if (attributeType == null || attributeType.IsAssignableFrom (t))
+ results.Add (cattrs [i].Invoke ());
+ }
+
+ return results.ToArray ();
}
public override FieldInfo GetField (string name, BindingFlags bindingAttr)
{
- return base.GetField (name, bindingAttr);
+ if (global_type_created == null)
+ throw new InvalidOperationException ("Module-level fields cannot be retrieved until after the CreateGlobalFunctions method has been called for the module.");
+ return global_type_created.GetField (name, bindingAttr);
}
public override FieldInfo[] GetFields (BindingFlags bindingFlags)
{
- return base.GetFields (bindingFlags);
+ if (global_type_created == null)
+ throw new InvalidOperationException ("Module-level fields cannot be retrieved until after the CreateGlobalFunctions method has been called for the module.");
+ return global_type_created.GetFields (bindingFlags);
}
public override MethodInfo[] GetMethods (BindingFlags bindingFlags)
{
- return base.GetMethods (bindingFlags);
+ if (global_type_created == null)
+ throw new InvalidOperationException ("Module-level methods cannot be retrieved until after the CreateGlobalFunctions method has been called for the module.");
+ return global_type_created.GetMethods (bindingFlags);
}
public override int MetadataToken {
get {
- return base.MetadataToken;
+ return get_MetadataToken (this);
}
}
}
diff --git a/mcs/class/corlib/Test/System.Reflection.Emit/ModuleBuilderTest.cs b/mcs/class/corlib/Test/System.Reflection.Emit/ModuleBuilderTest.cs
index e2574908f45..c1ae91971f9 100644
--- a/mcs/class/corlib/Test/System.Reflection.Emit/ModuleBuilderTest.cs
+++ b/mcs/class/corlib/Test/System.Reflection.Emit/ModuleBuilderTest.cs
@@ -116,7 +116,6 @@ namespace MonoTests.System.Reflection.Emit
}
[Test]
- [Category("NotWorking")]
public void TestGlobalMethods ()
{
AssemblyBuilder builder = genAssembly ();
@@ -859,5 +858,209 @@ namespace MonoTests.System.Reflection.Emit
Assert.AreEqual ("t1&", module.GetType ("t1&").FullName);
Assert.AreEqual ("t1[]&", module.GetType ("t1[]&").FullName);
}
+
+ [AttributeUsage(AttributeTargets.All)]
+ public class MyAttribute : Attribute {
+ public String Contents;
+ public MyAttribute (String contents)
+ {
+ this.Contents = contents;
+ }
+ }
+
+ [Test]
+ public void GetMethodsBeforeInstantiation ()
+ {
+ AssemblyBuilder assm = AssemblyBuilder.DefineDynamicAssembly (new AssemblyName ("Name"), AssemblyBuilderAccess.Run);
+ ModuleBuilder module = assm.DefineDynamicModule ("Module");
+
+ // Added to make sure fields and methods not mixed up by getters
+ FieldBuilder fieldBuilder = module.DefineInitializedData ("GlobalField", new byte[4], FieldAttributes.Public);
+
+ MethodBuilder method = module.DefinePInvokeMethod ("printf", "libc.so",
+ MethodAttributes.PinvokeImpl | MethodAttributes.Static | MethodAttributes.Public,
+ CallingConventions.Standard, typeof (void), new Type [] { typeof (string) }, CallingConvention.Winapi,
+ CharSet.Auto);
+ method.SetImplementationFlags (MethodImplAttributes.PreserveSig |
+ method.GetMethodImplementationFlags ());
+
+ module.CreateGlobalFunctions ();
+
+ // Make sure method is defined, but field is not
+ Assert.AreEqual (1, module.GetMethods (BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance).Length);
+ }
+
+ [Test]
+ public void GetFieldsBeforeInstantiation ()
+ {
+ AssemblyBuilder assm = AssemblyBuilder.DefineDynamicAssembly (new AssemblyName ("Name"), AssemblyBuilderAccess.Run);
+ ModuleBuilder module = assm.DefineDynamicModule ("Module");
+ FieldBuilder fieldBuilder = module.DefineInitializedData ("GlobalField", new byte[4], FieldAttributes.Public);
+ module.CreateGlobalFunctions ();
+
+ var fieldG = module.GetField (fieldBuilder.Name);
+ Assert.IsNotNull (fieldG);
+ Assert.AreEqual (1, module.GetFields (BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance).Length);
+ }
+
+ [Test]
+ public void GetCustomAttributesBeforeInstantiation ()
+ {
+ AssemblyBuilder assm = AssemblyBuilder.DefineDynamicAssembly (new AssemblyName ("Name"), AssemblyBuilderAccess.Run);
+ ModuleBuilder module = assm.DefineDynamicModule ("Module");
+ module.CreateGlobalFunctions ();
+
+ ConstructorInfo ctor = typeof(MyAttribute).GetConstructor (new Type [] {typeof(String)});
+ ctor.GetHashCode ();
+ CustomAttributeBuilder cab = new CustomAttributeBuilder (ctor, new object [] {"hi"});
+ module.SetCustomAttribute (cab);
+
+ Assert.AreEqual (1, module.GetCustomAttributes (false).Length);
+ Assert.AreEqual (typeof (MyAttribute), ((MyAttribute) module.GetCustomAttributes (false)[0]).GetType ());
+ Assert.AreEqual ("hi", ((MyAttribute) module.GetCustomAttributes (false)[0]).Contents);
+ }
+
+ [Test]
+ public void GetCustomAttributesIgnoresArg ()
+ {
+ AssemblyBuilder assm = AssemblyBuilder.DefineDynamicAssembly (new AssemblyName ("Name"), AssemblyBuilderAccess.Run);
+ ModuleBuilder module = assm.DefineDynamicModule ("Module");
+ module.CreateGlobalFunctions ();
+
+ ConstructorInfo ctor = typeof(MyAttribute).GetConstructor (new Type [] {typeof(String)});
+ ctor.GetHashCode ();
+ CustomAttributeBuilder cab = new CustomAttributeBuilder (ctor, new object [] {"hi"});
+ module.SetCustomAttribute (cab);
+
+ var first = module.GetCustomAttributes (false);
+ var second = module.GetCustomAttributes (true);
+
+ Assert.AreEqual (first.Length, second.Length);
+
+ for (int i=0; i < first.Length; i++)
+ Assert.AreEqual (first [i].GetType (), second [i].GetType ());
+
+ Assert.AreEqual ("hi", ((MyAttribute) first [0]).Contents);
+ Assert.AreEqual ("hi", ((MyAttribute) second [0]).Contents);
+ }
+
+ [Test]
+ public void GetCustomAttributesThrowsUnbakedAttributeType ()
+ {
+ AssemblyBuilder assm = AssemblyBuilder.DefineDynamicAssembly (new AssemblyName ("Name"), AssemblyBuilderAccess.Run);
+ ModuleBuilder module = assm.DefineDynamicModule ("Module");
+ TypeBuilder tb = module.DefineType ("foo");
+ module.CreateGlobalFunctions ();
+
+ ConstructorInfo ctor = typeof(MyAttribute).GetConstructor (new Type [] {typeof(String)});
+ ctor.GetHashCode ();
+ CustomAttributeBuilder cab = new CustomAttributeBuilder (ctor, new object [] {"hi"});
+ module.SetCustomAttribute (cab);
+
+ try {
+ module.GetCustomAttributes (tb, false);
+ }
+ catch (InvalidOperationException e) {
+ // Correct behavior
+ return;
+ }
+
+ Assert.Fail ("Supposed to throw");
+ }
+
+ [Test]
+ public void GetExternalTypeBuilderCAttr ()
+ {
+ AssemblyBuilder assm = AssemblyBuilder.DefineDynamicAssembly (new AssemblyName ("Name"), AssemblyBuilderAccess.Run);
+ ModuleBuilder module = assm.DefineDynamicModule ("Module");
+
+ ModuleBuilder module_two = assm.DefineDynamicModule ("ModuleTwo");
+ TypeBuilder tb = module_two.DefineType ("foo");
+
+ ConstructorInfo ctor = tb.DefineConstructor (MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes);
+ CustomAttributeBuilder cab = new CustomAttributeBuilder (ctor, Array.Empty<object> ());
+
+ // Set the custom attribute to have a type builder from another module
+ module.SetCustomAttribute (cab);
+
+ module.CreateGlobalFunctions ();
+
+ try {
+ module.GetCustomAttributes (false);
+ }
+ catch (NotSupportedException e) {
+ // Correct behavior
+ return;
+ }
+ Assert.Fail ("Supposed to throw");
+ }
+
+ [Test]
+ public void GetFieldsNoGlobalType ()
+ {
+ AssemblyBuilder assm = AssemblyBuilder.DefineDynamicAssembly (new AssemblyName ("Name"), AssemblyBuilderAccess.Run);
+ ModuleBuilder module = assm.DefineDynamicModule ("Module");
+ FieldBuilder fieldBuilder = module.DefineInitializedData ("GlobalField", new byte[4], FieldAttributes.Public);
+
+ try {
+ module.GetFields (BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
+ }
+ catch (InvalidOperationException e) {
+ // Correct behavior
+ return;
+ }
+ Assert.Fail ("Supposed to throw");
+ }
+
+ [Test]
+ public void GetFieldNoGlobalType ()
+ {
+ AssemblyBuilder assm = AssemblyBuilder.DefineDynamicAssembly (new AssemblyName ("Name"), AssemblyBuilderAccess.Run);
+ ModuleBuilder module = assm.DefineDynamicModule ("Module");
+ FieldBuilder fieldBuilder = module.DefineInitializedData ("GlobalField", new byte[4], FieldAttributes.Public);
+
+ try {
+ module.GetField (fieldBuilder.Name);
+ }
+ catch (InvalidOperationException e) {
+ // Correct behavior
+ return;
+ }
+ Assert.Fail ("Supposed to throw");
+ }
+
+ [Test]
+ public void GetMethodsNoGlobalType ()
+ {
+ AssemblyBuilder assm = AssemblyBuilder.DefineDynamicAssembly (new AssemblyName ("Name"), AssemblyBuilderAccess.Run);
+ ModuleBuilder module = assm.DefineDynamicModule ("Module");
+ FieldBuilder fieldBuilder = module.DefineInitializedData ("GlobalField", new byte[4], FieldAttributes.Public);
+
+ MethodBuilder method = module.DefinePInvokeMethod ("printf", "libc.so",
+ MethodAttributes.PinvokeImpl | MethodAttributes.Static | MethodAttributes.Public,
+ CallingConventions.Standard, typeof (void), new Type [] { typeof (string) }, CallingConvention.Winapi,
+ CharSet.Auto);
+ method.SetImplementationFlags (MethodImplAttributes.PreserveSig |
+ method.GetMethodImplementationFlags ());
+
+ try {
+ module.GetMethods (BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
+ }
+ catch (InvalidOperationException e) {
+ // Correct behavior
+ return;
+ }
+ Assert.Fail ("Supposed to throw");
+ }
+
+ [Test]
+ public void GetMetadataToken ()
+ {
+ AssemblyBuilder assm = AssemblyBuilder.DefineDynamicAssembly (new AssemblyName ("Name"), AssemblyBuilderAccess.Run);
+ ModuleBuilder module = assm.DefineDynamicModule ("Module");
+ module.CreateGlobalFunctions ();
+ Assert.AreEqual (0, module.MetadataToken);
+ }
+
}
}