未验证 提交 5d30e6da 编写于 作者: I Ivan Povazan 提交者: GitHub

[mono] Support function pointer reflection introspection API (#89712)

Fixes https://github.com/dotnet/runtime/issues/71095
上级 e8c46c24
......@@ -15,7 +15,6 @@ public partial class FunctionPointerCallingConventionTests
[Theory]
[InlineData(true)]
[InlineData(false)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void ManagedCallingConvention(bool modified)
{
Type t = typeof(FunctionPointerHolder).Project();
......@@ -36,7 +35,6 @@ public static unsafe void ManagedCallingConvention(bool modified)
[InlineData(nameof(FunctionPointerHolder.MethodCallConv_Stdcall))]
[InlineData(nameof(FunctionPointerHolder.MethodCallConv_Thiscall))]
[InlineData(nameof(FunctionPointerHolder.MethodCallConv_Fastcall))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void UnmanagedCallConv_Param_Unmodified(string methodName)
{
Type t = typeof(FunctionPointerHolder).Project();
......@@ -54,7 +52,6 @@ public static unsafe void UnmanagedCallConv_Param_Unmodified(string methodName)
[InlineData(nameof(FunctionPointerHolder.MethodCallConv_Stdcall), typeof(CallConvStdcall))]
[InlineData(nameof(FunctionPointerHolder.MethodCallConv_Thiscall), typeof(CallConvThiscall))]
[InlineData(nameof(FunctionPointerHolder.MethodCallConv_Fastcall), typeof(CallConvFastcall))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void UnmanagedCallConv_Param_Modified(string methodName, Type callingConventionRuntime)
{
Type callingConvention = callingConventionRuntime.Project();
......@@ -71,7 +68,7 @@ public static unsafe void UnmanagedCallConv_Param_Modified(string methodName, Ty
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/90308", TestRuntimes.Mono)]
public static unsafe void UnmanagedCallConvs_Return_Unmodified()
{
Type t = typeof(FunctionPointerHolder).Project();
......@@ -91,7 +88,6 @@ public static unsafe void UnmanagedCallConvs_Return_Unmodified()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void UnmanagedCallConvs_Return_Modified()
{
Type t = typeof(FunctionPointerHolder).Project();
......@@ -118,7 +114,6 @@ public static unsafe void UnmanagedCallConvs_Return_Modified()
[InlineData(nameof(FunctionPointerHolder.MethodCallConv_Stdcall_SuppressGCTransition))]
[InlineData(nameof(FunctionPointerHolder.MethodCallConv_Thiscall_SuppressGCTransition))]
[InlineData(nameof(FunctionPointerHolder.MethodCallConv_Fastcall_SuppressGCTransition))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void UnmanagedCallConv_PhysicalModifiers_Unmodified(string methodName)
{
Type t = typeof(FunctionPointerHolder).Project();
......@@ -137,7 +132,6 @@ public static unsafe void UnmanagedCallConv_PhysicalModifiers_Unmodified(string
[InlineData(nameof(FunctionPointerHolder.MethodCallConv_Stdcall_SuppressGCTransition), typeof(CallConvStdcall))]
[InlineData(nameof(FunctionPointerHolder.MethodCallConv_Thiscall_SuppressGCTransition), typeof(CallConvThiscall))]
[InlineData(nameof(FunctionPointerHolder.MethodCallConv_Fastcall_SuppressGCTransition), typeof(CallConvFastcall))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void UnmanagedCallConv_PhysicalModifiers_Modified(string methodName, Type callingConventionRuntime)
{
Type suppressGcTransitionType = typeof(CallConvSuppressGCTransition).Project();
......@@ -161,7 +155,6 @@ public static unsafe void UnmanagedCallConv_PhysicalModifiers_Modified(string me
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void GenericTypeParameter()
{
Type holder = typeof(FunctionPointerHolder).Project();
......
......@@ -15,7 +15,6 @@ public partial class FunctionPointerEqualityTests
private const BindingFlags Bindings = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly;
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void DifferentReturnValue()
{
Type t = typeof(FunctionPointerHolder).Project();
......@@ -31,7 +30,6 @@ public static unsafe void DifferentReturnValue()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void ObjectEquals_ModifiedTypes()
{
Type holder = typeof(FunctionPointerHolder).Project();
......@@ -47,7 +45,6 @@ public static unsafe void ObjectEquals_ModifiedTypes()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void ObjectEquals_OneSideModifiedType()
{
Type holder = typeof(FunctionPointerHolder).Project();
......@@ -65,7 +62,7 @@ public static unsafe void ObjectEquals_OneSideModifiedType()
[InlineData(nameof(FunctionPointerHolder.MethodCallConv_Cdecl), nameof(FunctionPointerHolder.MethodCallConv_Stdcall))]
[InlineData(nameof(FunctionPointerHolder.MethodCallConv_Cdecl), nameof(FunctionPointerHolder.MethodCallConv_Thiscall))]
[InlineData(nameof(FunctionPointerHolder.MethodCallConv_Cdecl), nameof(FunctionPointerHolder.MethodCallConv_Fastcall))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/90308", TestRuntimes.Mono)]
public static unsafe void CallingConvention_Unmodified(string methodName1, string methodName2)
{
Type t = typeof(FunctionPointerHolder).Project();
......@@ -83,7 +80,6 @@ public static unsafe void CallingConvention_Unmodified(string methodName1, strin
[InlineData(nameof(FunctionPointerHolder.MethodCallConv_Cdecl), nameof(FunctionPointerHolder.MethodCallConv_Stdcall))]
[InlineData(nameof(FunctionPointerHolder.MethodCallConv_Cdecl), nameof(FunctionPointerHolder.MethodCallConv_Thiscall))]
[InlineData(nameof(FunctionPointerHolder.MethodCallConv_Cdecl), nameof(FunctionPointerHolder.MethodCallConv_Fastcall))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void CallingConvention_Modified(string methodName1, string methodName2)
{
Type t = typeof(FunctionPointerHolder).Project();
......
......@@ -14,7 +14,6 @@ public partial class FunctionPointerTests
private const BindingFlags Bindings = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly;
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void TypeMembers()
{
// Get an arbitrary function pointer
......@@ -116,7 +115,6 @@ public static unsafe void TypeMembers()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void NonFunctionPointerThrows()
{
Assert.Throws<InvalidOperationException>(() => typeof(int).GetFunctionPointerCallingConventions());
......@@ -125,7 +123,6 @@ public static unsafe void NonFunctionPointerThrows()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void TestToString()
{
// Function pointer types are inline in metadata and can't be loaded independently so they do not support the
......@@ -146,7 +143,6 @@ public static unsafe void TestToString()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void FunctionPointerReturn()
{
Type t = typeof(FunctionPointerHolder).Project();
......@@ -163,7 +159,6 @@ public static unsafe void FunctionPointerReturn()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void RequiredModifiers()
{
Type t = typeof(FunctionPointerHolder).Project();
......@@ -188,7 +183,6 @@ public static unsafe void RequiredModifiers()
"Double",
"System.Double(System.String, System.Boolean*&, System.Tests.Types.FunctionPointerTests+FunctionPointerHolder+MyClass, System.Tests.Types.FunctionPointerTests+FunctionPointerHolder+MyStruct&)",
"String", "Boolean*&", "MyClass", "MyStruct&")]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void MethodInfo(
string methodName,
string methodToStringPostfix,
......@@ -216,7 +210,6 @@ public static unsafe void RequiredModifiers()
[Theory]
[InlineData(nameof(FunctionPointerHolder.Prop_Int), "System.Int32()")]
[InlineData(nameof(FunctionPointerHolder.Prop_MyClass), "System.Tests.Types.FunctionPointerTests+FunctionPointerHolder+MyClass()")]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void Property(string name, string expectedToString)
{
Type t = typeof(FunctionPointerHolder).Project();
......@@ -235,7 +228,6 @@ public static unsafe void Property(string name, string expectedToString)
[Theory]
[InlineData(nameof(FunctionPointerHolder.Field_Int), "System.Int32()")]
[InlineData(nameof(FunctionPointerHolder.Field_MyClass), "System.Tests.Types.FunctionPointerTests+FunctionPointerHolder+MyClass()")]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void Field(string name, string expectedToString)
{
Type t = typeof(FunctionPointerHolder).Project();
......
......@@ -17,7 +17,6 @@ public partial class ModifiedTypeTests
private const BindingFlags Bindings = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly;
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void TypeMembers()
{
FieldInfo fi = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._volatileInt), Bindings);
......@@ -153,7 +152,6 @@ void ModifiedTypeMembers(Type t)
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void Fields_Modified()
{
Type volatileInt = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._volatileInt), Bindings).GetModifiedFieldType();
......@@ -191,7 +189,6 @@ void Verify(Type type)
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void Fields_Generic_Unmodified()
{
Type arrayGenericFcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._arrayGenericFcnPtr), Bindings).FieldType;
......@@ -212,7 +209,6 @@ public static unsafe void Fields_Generic_Unmodified()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void Fields_Generic_Modified()
{
Type arrayGenericFcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._arrayGenericFcnPtr), Bindings).GetModifiedFieldType();
......@@ -235,7 +231,6 @@ public static unsafe void Fields_Generic_Modified()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void Methods_OpenGeneric_Unmodified()
{
MethodInfo mi = typeof(ModifiedTypeHolder).Project().GetMethod(nameof(ModifiedTypeHolder.M_ArrayOpenGenericFcnPtr), Bindings);
......@@ -258,7 +253,6 @@ public static unsafe void Methods_OpenGeneric_Unmodified()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void Methods_OpenGeneric_Modified()
{
MethodInfo mi = typeof(ModifiedTypeHolder).Project().GetMethod(nameof(ModifiedTypeHolder.M_ArrayOpenGenericFcnPtr), Bindings);
......@@ -283,7 +277,6 @@ public static unsafe void Methods_OpenGeneric_Modified()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void Fields_Unmodified()
{
Type volatileInt = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._volatileInt), Bindings).FieldType;
......@@ -315,7 +308,6 @@ void Verify(Type type)
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void Fields_Parameterized_Basic()
{
Type ptr_ptr_int = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._ptr_ptr_int), Bindings).GetModifiedFieldType();
......@@ -336,7 +328,6 @@ void Verify(Type type)
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void Fields_Parameterized_FcnPtr()
{
Type ptr_fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._ptr_fcnPtr), Bindings).GetModifiedFieldType();
......@@ -367,7 +358,6 @@ void Verify(Type type)
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void Fields_VerifyIdempotency()
{
// Call these again to ensure any backing caching strategy works.
......@@ -378,7 +368,6 @@ public static unsafe void Fields_VerifyIdempotency()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void MethodParameters()
{
ParameterInfo[] parameters = typeof(ModifiedTypeHolder).Project().GetMethod(nameof(ModifiedTypeHolder.M_P0IntOut), Bindings).GetParameters();
......@@ -402,7 +391,6 @@ public static unsafe void MethodParameters()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void ConstructorParameters_Unmodified()
{
ParameterInfo[] parameters = typeof(ModifiedTypeHolder).Project().GetConstructors()[0].GetParameters();
......@@ -415,7 +403,6 @@ public static unsafe void ConstructorParameters_Unmodified()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void ConstructorParameters_Modified()
{
ParameterInfo[] parameters = typeof(ModifiedTypeHolder).Project().GetConstructors()[0].GetParameters();
......@@ -429,7 +416,6 @@ public static unsafe void ConstructorParameters_Modified()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void FunctionPointerParameters_fcnPtrP0Out_Unmodified()
{
Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtrP0Out), Bindings).GetModifiedFieldType();
......@@ -440,7 +426,6 @@ public static unsafe void FunctionPointerParameters_fcnPtrP0Out_Unmodified()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void FunctionPointerParameters_fcnPtrP0Out_Modified()
{
Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtrP0Out), Bindings).FieldType;
......@@ -451,7 +436,6 @@ public static unsafe void FunctionPointerParameters_fcnPtrP0Out_Modified()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Out_Unmodified()
{
Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtr_fcnPtrP0Out), Bindings).FieldType;
......@@ -464,7 +448,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Out_Unmodifie
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Out_Modified()
{
// Modified
......@@ -479,7 +462,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Out_Modified(
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Ref_Unmodified()
{
Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtr_fcnPtrP0Ref), Bindings).FieldType;
......@@ -493,7 +475,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Ref_Unmodifie
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Ref_Modified()
{
Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtr_fcnPtrP0Ref), Bindings).GetModifiedFieldType();
......@@ -507,7 +488,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Ref_Modified(
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrRetP0Ref_Unmodified()
{
Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtr_fcnPtrRetP0Out), Bindings).FieldType;
......@@ -518,7 +498,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrRetP0Ref_Unmodi
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrRetP0Ref_Modified()
{
Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtr_fcnPtrRetP0Out), Bindings).GetModifiedFieldType();
......@@ -530,7 +509,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrRetP0Ref_Modifi
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void FunctionPointerParameters_fcnPtr_complex_Unmodified()
{
Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtr_complex), Bindings).FieldType;
......@@ -554,7 +532,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_complex_Unmodified()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void FunctionPointerParameters_fcnPtr_complex_Modified()
{
Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtr_complex), Bindings).GetModifiedFieldType();
......@@ -579,7 +556,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_complex_Modified()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void Property_FcnPtr_Complex_Unmodified()
{
Type mt = typeof(ModifiedTypeHolder).Project().GetProperty(nameof(ModifiedTypeHolder.Property_FcnPtr_Complex), Bindings).PropertyType;
......@@ -596,7 +572,6 @@ public static unsafe void Property_FcnPtr_Complex_Unmodified()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void Property_FcnPtr_Complex_Modified()
{
Type mt = typeof(ModifiedTypeHolder).Project().GetProperty(nameof(ModifiedTypeHolder.Property_FcnPtr_Complex), Bindings).GetModifiedPropertyType();
......@@ -614,15 +589,17 @@ public static unsafe void Property_FcnPtr_Complex_Modified()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void MethodWithGenericParameter_Unmodified()
public static unsafe void MethodWithGenericParameterWithModifiers_Unmodified()
{
MethodInfo mi = typeof(GenericWithModifiers).Project().GetMethod(nameof(GenericWithModifiers.MethodWithGenericParameter), Bindings);
Assert.False(mi.ContainsGenericParameters);
Type a1 = mi.GetParameters()[0].ParameterType;
Assert.False(IsModifiedType(a1));
Assert.Equal(typeof(Tuple<int, bool>).Project(), a1.Project());
// https://github.com/dotnet/runtime/issues/90308"
if (!PlatformDetection.IsMonoRuntime)
Assert.Equal(typeof(Tuple<int, bool>).Project(), a1.Project());
Type ga1 = a1.GetGenericArguments()[0];
Assert.False(IsModifiedType(ga1));
......@@ -635,15 +612,17 @@ public static unsafe void MethodWithGenericParameter_Unmodified()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void MethodWithGenericParameter_Modified()
public static unsafe void MethodWithGenericParameterWithModifiers_Modified()
{
MethodInfo mi = typeof(GenericWithModifiers).Project().GetMethod(nameof(GenericWithModifiers.MethodWithGenericParameter), Bindings);
Assert.False(mi.ContainsGenericParameters);
Type a1 = mi.GetParameters()[0].GetModifiedParameterType();
Assert.True(IsModifiedType(a1));
Assert.Equal(typeof(Tuple<int, bool>).Project(), a1.UnderlyingSystemType.Project());
// https://github.com/dotnet/runtime/issues/90308"
if (!PlatformDetection.IsMonoRuntime)
Assert.Equal(typeof(Tuple<int, bool>).Project(), a1.UnderlyingSystemType.Project());
Type ga1 = a1.GetGenericArguments()[0];
Assert.True(IsModifiedType(ga1));
......@@ -658,7 +637,98 @@ public static unsafe void MethodWithGenericParameter_Modified()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void GenericFieldWithModifiers_Unmodified()
{
FieldInfo fi = typeof(GenericWithModifiers).Project().GetField(nameof(GenericWithModifiers.GenericField), Bindings);
Type ft = fi.FieldType;
Assert.False(IsModifiedType(ft));
// https://github.com/dotnet/runtime/issues/90308"
if (!PlatformDetection.IsMonoRuntime)
Assert.Equal(typeof(Tuple<int, bool>).Project(), ft.Project());
Type ga1 = ft.GetGenericArguments()[0];
Assert.False(IsModifiedType(ga1));
Assert.Equal(typeof(int).Project(), ga1);
Type ga2 = ft.GetGenericArguments()[1];
Assert.False(IsModifiedType(ga2));
Assert.Equal(typeof(bool).Project(), ga2);
Assert.Equal(0, ga2.GetOptionalCustomModifiers().Length);
}
[Fact]
public static unsafe void GenericFieldWithModifiers_Modified()
{
FieldInfo fi = typeof(GenericWithModifiers).Project().GetField(nameof(GenericWithModifiers.GenericField), Bindings);
Type ft = fi.GetModifiedFieldType();
Assert.True(IsModifiedType(ft));
// https://github.com/dotnet/runtime/issues/90308"
if (!PlatformDetection.IsMonoRuntime)
Assert.Equal(typeof(Tuple<int, bool>).Project(), ft.UnderlyingSystemType.Project());
Type ga1 = ft.GetGenericArguments()[0];
Assert.True(IsModifiedType(ga1));
Assert.Equal(typeof(int).Project(), ga1.UnderlyingSystemType);
Assert.Equal(0, ga1.GetOptionalCustomModifiers().Length);
Type ga2 = ft.GetGenericArguments()[1];
Assert.True(IsModifiedType(ga2));
Assert.Equal(typeof(bool).Project(), ga2.UnderlyingSystemType);
Assert.Equal(1, ga2.GetOptionalCustomModifiers().Length);
Assert.Equal(typeof(IsConst).Project(), ga2.GetOptionalCustomModifiers()[0]);
}
[Fact]
public static unsafe void GenericPropertyWithModifiers_Unmodified()
{
PropertyInfo pi = typeof(GenericWithModifiers).Project().GetProperty(nameof(GenericWithModifiers.GenericProperty), Bindings);
Type pt = pi.PropertyType;
Assert.False(IsModifiedType(pt));
// https://github.com/dotnet/runtime/issues/90308"
if (!PlatformDetection.IsMonoRuntime)
Assert.Equal(typeof(Tuple<int, bool>).Project(), pt.Project());
Type ga1 = pt.GetGenericArguments()[0];
Assert.False(IsModifiedType(ga1));
Assert.Equal(typeof(int).Project(), ga1);
Type ga2 = pt.GetGenericArguments()[1];
Assert.False(IsModifiedType(ga2));
Assert.Equal(typeof(bool).Project(), ga2);
Assert.Equal(0, ga2.GetOptionalCustomModifiers().Length);
}
[Fact]
public static unsafe void GenericPropertyWithModifiers_Modified()
{
PropertyInfo pi = typeof(GenericWithModifiers).Project().GetProperty(nameof(GenericWithModifiers.GenericProperty), Bindings);
Type pt = pi.GetModifiedPropertyType();
Assert.True(IsModifiedType(pt));
// https://github.com/dotnet/runtime/issues/90308"
if (!PlatformDetection.IsMonoRuntime)
Assert.Equal(typeof(Tuple<int, bool>).Project(), pt.UnderlyingSystemType.Project());
Type ga1 = pt.GetGenericArguments()[0];
Assert.True(IsModifiedType(ga1));
Assert.Equal(typeof(int).Project(), ga1.UnderlyingSystemType);
Assert.Equal(0, ga1.GetOptionalCustomModifiers().Length);
Type ga2 = pt.GetGenericArguments()[1];
Assert.True(IsModifiedType(ga2));
Assert.Equal(typeof(bool).Project(), ga2.UnderlyingSystemType);
Assert.Equal(1, ga2.GetOptionalCustomModifiers().Length);
Assert.Equal(typeof(IsConst).Project(), ga2.GetOptionalCustomModifiers()[0]);
}
[Fact]
public static unsafe void GenericMethod_Unmodified()
{
MethodInfo mi = typeof(GenericWithModifiers).Project().GetMethod(nameof(GenericWithModifiers.GenericMethod), Bindings);
......@@ -671,7 +741,6 @@ public static unsafe void GenericMethod_Unmodified()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static unsafe void GenericMethod_Modified()
{
MethodInfo mi = typeof(GenericWithModifiers).Project().GetMethod(nameof(GenericWithModifiers.GenericMethod), Bindings);
......@@ -684,7 +753,6 @@ public static unsafe void GenericMethod_Modified()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static void ParameterConstraints1()
{
MethodInfo mi = typeof(ModifiedTypeHolder).Project().GetMethod(nameof(ModifiedTypeHolder.M_GenericWithParameterConstraint1), Bindings);
......@@ -709,7 +777,6 @@ public static void ParameterConstraints1()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public static void ParameterConstraints2()
{
MethodInfo mi = typeof(ModifiedTypeHolder).Project().GetMethod(nameof(ModifiedTypeHolder.M_GenericWithParameterConstraint2), Bindings);
......
......@@ -42,5 +42,20 @@
IL_0000: nop
IL_0001: ret
}
.field public class [System.Runtime]System.Tuple`2<int32,bool modopt([System.Runtime]System.Runtime.CompilerServices.IsConst)> GenericField
.method public hidebysig specialname instance class [System.Runtime]System.Tuple`2<int32,bool modopt([System.Runtime]System.Runtime.CompilerServices.IsConst)> get_GenericField () cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld class [System.Runtime]System.Tuple`2<int32,bool modopt([System.Runtime]System.Runtime.CompilerServices.IsConst)> System.Tests.GenericWithModifiers::GenericField
IL_0006: ret
}
.property instance class [System.Runtime]System.Tuple`2<int32,bool modopt([System.Runtime]System.Runtime.CompilerServices.IsConst)> GenericProperty()
{
.get instance class [System.Runtime]System.Tuple`2<int32,bool modopt([System.Runtime]System.Runtime.CompilerServices.IsConst)> System.Tests.GenericWithModifiers::get_GenericField()
}
}
}
......@@ -5,4 +5,5 @@
ILLink completely trims it out. So, preserve it explicitly.
-->
<assembly fullname="mscorlib" />
<assembly fullname="TestILAssembly" />
</linker>
<linker>
<assembly fullname="TestLoadAssembly" />
<assembly fullname="TestILAssembly" />
</linker>
......@@ -198,13 +198,8 @@ public static IEnumerable<object[]> CreateInstance_NoDefaultConstructor_TestData
yield return new object[] { typeof(int[]) };
yield return new object[] { typeof(int).MakeByRefType() };
yield return new object[] { typeof(int).MakePointerType() };
// https://github.com/dotnet/runtime/issues/71095
if (!PlatformDetection.IsMonoRuntime)
{
yield return new object[] { FunctionPointerType() };
static unsafe Type FunctionPointerType() => typeof(delegate*<int, int>);
}
yield return new object[] { FunctionPointerType() };
static unsafe Type FunctionPointerType() => typeof(delegate*<int, int>);
}
[Theory]
......
......@@ -58,7 +58,6 @@ public void Properties()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
public void FunctionPointers()
{
Assert.True(new TypeDelegator(typeof(delegate*<void>)).IsFunctionPointer);
......
......@@ -228,12 +228,8 @@ public static IEnumerable<object[]> GetUninitializedObject_NegativeTestCases()
yield return new[] { typeof(int).MakePointerType(), typeof(ArgumentException) }; // pointer
yield return new[] { typeof(int).MakeByRefType(), typeof(ArgumentException) }; // byref
// https://github.com/dotnet/runtime/issues/71095
if (!PlatformDetection.IsMonoRuntime)
{
yield return new[] { FunctionPointerType(), typeof(ArgumentException) }; // function pointer
static unsafe Type FunctionPointerType() => typeof(delegate*<void>);
}
yield return new[] { FunctionPointerType(), typeof(ArgumentException) }; // function pointer
static unsafe Type FunctionPointerType() => typeof(delegate*<void>);
yield return new[] { typeof(ReadOnlySpan<int>), typeof(NotSupportedException) }; // byref-like type
yield return new[] { typeof(ArgIterator), typeof(NotSupportedException) }; // byref-like type
......
......@@ -12,7 +12,7 @@ namespace System.Tests.Types
public partial class FunctionPointerTests
{
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/90308", TestRuntimes.Mono)]
public static unsafe void CompileTimeIdentity_Managed()
{
object obj = new delegate*<int>[1];
......@@ -27,7 +27,7 @@ public static unsafe void CompileTimeIdentity_Managed()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/90308", TestRuntimes.Mono)]
public static unsafe void CompileTimeIdentity_ManagedWithMods()
{
object obj = new delegate*<ref int, void>[1];
......@@ -42,7 +42,7 @@ public static unsafe void CompileTimeIdentity_ManagedWithMods()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/90308", TestRuntimes.Mono)]
public static unsafe void CompileTimeIdentity_Unmanaged()
{
object obj = new delegate* unmanaged[MemberFunction]<void>[1];
......@@ -59,7 +59,7 @@ public static unsafe void CompileTimeIdentity_Unmanaged()
}
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/90308", TestRuntimes.Mono)]
public static unsafe void CompileTimeIdentity_UnmanagedIsPartOfIdentity()
{
object obj = new delegate* unmanaged[MemberFunction]<void>[1];
......
......@@ -964,13 +964,8 @@ public static IEnumerable<object[]> InvalidGenericArgumentTypes()
yield return new object[] { typeof(void) };
yield return new object[] { typeof(object).MakeByRefType() };
yield return new object[] { typeof(int).MakePointerType() };
// https://github.com/dotnet/runtime/issues/71095
if (!PlatformDetection.IsMonoRuntime)
{
yield return new object[] { FunctionPointerType() };
static unsafe Type FunctionPointerType() => typeof(delegate*<void>);
}
yield return new object[] { FunctionPointerType() };
static unsafe Type FunctionPointerType() => typeof(delegate*<void>);
}
[Theory]
......
......@@ -5,16 +5,151 @@ namespace System.Reflection
{
internal partial class ModifiedType
{
/// <summary>
/// Holds type signature information about the modified type
/// It can have two sources for signatures:
/// - SignatureHolderType - holds function pointer type signature
/// - SignatureHolderInfo - holds field/property/parameter type signature
/// This comes down of having three different scenarios:
/// 1. Only SignatureHolderInfo holds signature information, example:
/// volatile int intField;
/// 2. Only SignatureHolderType holds signature information, example:
/// delegate* unmanaged[Cdecl]&lt;int&gt; fptrField1;
/// 3. Both SignatureHolderType and SignatureHolderInfo hold signature information, example:
/// volatile delegate* unmanaged[Cdecl]&lt;int&gt; fptrField2;
/// NOTE: In scenario 3) the SignatureHolderInfo has higher priority for retrieving field data (like custom modifiers)
/// </summary>
internal struct TypeSignature
{
internal readonly RuntimeType? SignatureHolderType;
internal readonly object? SignatureHolderInfo;
internal int ParameterIndex;
internal TypeSignature(RuntimeType signatureHolderType, int parameterIndex)
{
SignatureHolderType = signatureHolderType;
SignatureHolderInfo = null;
ParameterIndex = parameterIndex;
}
internal TypeSignature(object signatureHolderInfo, int parameterIndex)
{
SignatureHolderType = null;
SignatureHolderInfo = signatureHolderInfo;
ParameterIndex = parameterIndex;
}
internal TypeSignature(RuntimeType signatureHolderType, object signatureHolderInfo, int parameterIndex)
{
SignatureHolderType = signatureHolderType;
SignatureHolderInfo = signatureHolderInfo;
ParameterIndex = parameterIndex;
}
internal bool TryGetCustomModifiersFromSignatureHolderInfo(bool required, out Type[] modifiers)
{
if (SignatureHolderInfo is null)
{
modifiers = Type.EmptyTypes;
return false;
}
else
{
switch (SignatureHolderInfo)
{
case RuntimeFieldInfo fieldInfo:
modifiers = fieldInfo.GetCustomModifiersFromModifiedType(!required, fieldInfo.FieldType.IsGenericType ? ParameterIndex : -1);
break;
case RuntimeParameterInfo parameterInfo:
modifiers = parameterInfo.GetCustomModifiersFromModifiedType(!required, parameterInfo.ParameterType.IsGenericType ? ParameterIndex : -1);
break;
case RuntimePropertyInfo propertyInfo:
modifiers = propertyInfo.GetCustomModifiersFromModifiedType(!required, propertyInfo.PropertyType.IsGenericType ? ParameterIndex : -1);
break;
default:
throw new Exception($"SignatureHolderInfo: {SignatureHolderInfo} is not recognized");
}
return true;
}
}
internal bool TryGetCustomModifiersFromSignatureHolderType(bool required, out Type[] modifiers)
{
if (SignatureHolderType is null)
{
modifiers = Type.EmptyTypes;
return false;
}
else
{
modifiers = SignatureHolderType.GetCustomModifiersFromFunctionPointer(ParameterIndex, optional: !required);
return true;
}
}
}
internal static Type Create(Type sourceType, object sourceTypeInfo, int parameterIndex = 0)
{
var unmodifiedType = (RuntimeType)sourceType;
TypeSignature typeSignature;
if (unmodifiedType.IsFunctionPointer)
typeSignature = new TypeSignature(unmodifiedType, sourceTypeInfo, parameterIndex);
else
typeSignature = new TypeSignature(sourceTypeInfo, parameterIndex);
return Create(unmodifiedType, typeSignature);
}
#pragma warning disable IDE0060
internal Type GetTypeParameter(Type unmodifiedType, int index) => throw new NotSupportedException();
// If the current unmodifiedType is a function pointer that means that the signature holder for the modified type
// (and all its children types) becomes the unmodifiedType. At the same time, if the current or parent unmodified
// types are function pointers, then SignatureHolderInfo becomes irrelevant as there is no more dependency on fetching
// custom modifiers from parent's field/param/property info.
// In all other cases, we pass parent's type signature information down the hierarchy.
internal Type GetTypeParameter(Type unmodifiedType, int index)
{
var parentUnmodifiedType = UnmodifiedType;
var childUnmodifiedType = (RuntimeType)unmodifiedType;
TypeSignature childTypeSignature;
internal SignatureCallingConvention GetCallingConventionFromFunctionPointer() => throw new NotSupportedException();
if (childUnmodifiedType.IsFunctionPointer)
{
childTypeSignature = new TypeSignature(childUnmodifiedType, index);
}
else
{
if (parentUnmodifiedType.IsFunctionPointer)
{
var parentSignatureHolderType = _typeSignature.SignatureHolderType ??
throw new Exception($"Parent's {nameof(_typeSignature.SignatureHolderType)} cannot be null");
childTypeSignature = new TypeSignature(parentSignatureHolderType, index);
}
else
{
var parentSignatureHolderInfo = _typeSignature.SignatureHolderInfo ??
throw new Exception($"Parent's {nameof(_typeSignature.SignatureHolderInfo)} cannot be null");
childTypeSignature = new TypeSignature(parentSignatureHolderInfo, index);
}
}
private Type[] GetCustomModifiers(bool required) => throw new NotSupportedException();
#pragma warning restore IDE0060
return Create(childUnmodifiedType, childTypeSignature);
}
internal SignatureCallingConvention GetCallingConventionFromFunctionPointer()
{
if (_typeSignature.SignatureHolderType is null)
throw new Exception($"{nameof(_typeSignature.SignatureHolderType)} cannot be null when retrieving calling conventions from a function pointer type ");
return _typeSignature.SignatureHolderType.GetCallingConventionFromFunctionPointer();
}
private Type[] GetCustomModifiers(bool required)
{
if (_typeSignature.TryGetCustomModifiersFromSignatureHolderInfo(required, out var modifiersFromInfo))
return modifiersFromInfo;
else if (_typeSignature.TryGetCustomModifiersFromSignatureHolderType(required, out var modifiersFromType))
return modifiersFromType;
else
throw new Exception($"Failed to retrieve custom modifiers on a modified type: {this}");
}
}
}
......@@ -291,12 +291,16 @@ public override int MetadataToken
internal static extern int get_metadata_token(RuntimeFieldInfo monoField);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern Type[] GetTypeModifiers(bool optional);
private extern Type[] GetTypeModifiers(bool optional, int genericArgumentPosition = -1);
public override Type[] GetOptionalCustomModifiers() => GetCustomModifiers(true);
public override Type[] GetRequiredCustomModifiers() => GetCustomModifiers(false);
private Type[] GetCustomModifiers(bool optional) => GetTypeModifiers(optional) ?? Type.EmptyTypes;
internal Type[] GetCustomModifiersFromModifiedType(bool optional, int genericArgumentPosition) => GetTypeModifiers(optional, genericArgumentPosition) ?? Type.EmptyTypes;
public override Type GetModifiedFieldType() => ModifiedType.Create(FieldType, this);
}
}
......@@ -394,7 +394,7 @@ public override bool HasDefaultValue
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern Type[] GetTypeModifiers(Type type, MemberInfo member, int position, bool optional);
internal static extern Type[] GetTypeModifiers(Type type, MemberInfo member, int position, bool optional, int genericArgumentPosition = -1);
internal static ParameterInfo New(ParameterInfo pinfo, Type? type, MemberInfo member, int position)
{
......@@ -422,5 +422,9 @@ internal void SetAttributes(ParameterAttributes attributes)
}
private Type[] GetCustomModifiers(bool optional) => GetTypeModifiers(ParameterType, Member, Position, optional) ?? Type.EmptyTypes;
internal Type[] GetCustomModifiersFromModifiedType(bool optional, int genericArgumentPosition) => GetTypeModifiers(ParameterType, Member, Position, optional, genericArgumentPosition) ?? Type.EmptyTypes;
public override Type GetModifiedParameterType() => ModifiedType.Create(ParameterType, this, PositionImpl + 1);
}
}
......@@ -77,7 +77,7 @@ internal sealed class RuntimePropertyInfo : PropertyInfo
PInfo req_info);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern Type[] GetTypeModifiers(RuntimePropertyInfo prop, bool optional);
internal static extern Type[] GetTypeModifiers(RuntimePropertyInfo prop, bool optional, int genericArgumentPosition = -1);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern object get_default_value(RuntimePropertyInfo prop);
......@@ -506,5 +506,9 @@ internal static PropertyInfo GetPropertyFromHandle(RuntimePropertyHandle handle,
throw new ArgumentException(SR.Argument_FieldPropertyEventAndTypeHandleIncompatibility);
return pi;
}
internal Type[] GetCustomModifiersFromModifiedType(bool optional, int genericArgumentPosition) => GetTypeModifiers(this, optional, genericArgumentPosition) ?? Type.EmptyTypes;
public override Type GetModifiedPropertyType() => ModifiedType.Create(PropertyType, this);
}
}
......@@ -2400,6 +2400,82 @@ public override bool IsSZArray
}
}
public override bool IsFunctionPointer => RuntimeTypeHandle.IsFunctionPointer(this);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool IsUnmanagedFunctionPointerInternal(QCallTypeHandle type);
internal static bool IsUnmanagedFunctionPointerInternal(RuntimeType type)
{
return IsUnmanagedFunctionPointerInternal(new QCallTypeHandle(ref type));
}
public override bool IsUnmanagedFunctionPointer => IsUnmanagedFunctionPointerInternal(this);
public override Type[] GetFunctionPointerParameterTypes()
{
Type[] parameters = FunctionPointerReturnAndParameterTypes(this, false);
return parameters.Length == 0 ? EmptyTypes : parameters;
}
public override Type GetFunctionPointerReturnType()
{
return FunctionPointerReturnAndParameterTypes(this, true)[0];
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern IntPtr FunctionPointerReturnAndParameterTypes(QCallTypeHandle type);
internal static Type[] FunctionPointerReturnAndParameterTypes(RuntimeType type, bool returnType)
{
if (!RuntimeTypeHandle.IsFunctionPointer(type))
{
throw new InvalidOperationException(SR.InvalidOperation_NotFunctionPointer);
}
using (var arrayOfTypeHandles = new Mono.SafeGPtrArrayHandle(FunctionPointerReturnAndParameterTypes(new QCallTypeHandle(ref type))))
{
int typeNum = returnType ? 1 : arrayOfTypeHandles.Length - 1;
var fPtrReturnAndParameterTypes = new Type[typeNum];
if (returnType)
{
var typeHandle = new RuntimeTypeHandle(arrayOfTypeHandles[0]);
fPtrReturnAndParameterTypes[0] = (RuntimeType)GetTypeFromHandle(typeHandle)!;
}
else
{
for (int i = 1; i < typeNum + 1; i++)
{
var typeHandle = new RuntimeTypeHandle(arrayOfTypeHandles[i]);
fPtrReturnAndParameterTypes[i-1] = (RuntimeType)GetTypeFromHandle(typeHandle)!;
}
}
return fPtrReturnAndParameterTypes;
}
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern Type[] GetFunctionPointerTypeModifiers(QCallTypeHandle type, int position, bool optional);
internal static Type[] GetFunctionPointerTypeModifiers(RuntimeType type, int position, bool optional) => GetFunctionPointerTypeModifiers(new QCallTypeHandle(ref type), position, optional) ?? Type.EmptyTypes;
public Type[] GetCustomModifiersFromFunctionPointer(int position, bool optional) => GetFunctionPointerTypeModifiers(this, position, optional);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern byte GetCallingConventionFromFunctionPointerInternal(QCallTypeHandle type);
internal static byte GetCallingConventionFromFunctionPointerInternal(RuntimeType type) => GetCallingConventionFromFunctionPointerInternal(new QCallTypeHandle(ref type));
public SignatureCallingConvention GetCallingConventionFromFunctionPointer() => (SignatureCallingConvention)GetCallingConventionFromFunctionPointerInternal(this);
public override Type[] GetFunctionPointerCallingConventions()
{
if (!RuntimeTypeHandle.IsFunctionPointer(this))
throw new InvalidOperationException(SR.InvalidOperation_NotFunctionPointer);
// Requires a modified type to return the modifiers.
return EmptyTypes;
}
internal override bool IsUserType
{
get
......
......@@ -418,6 +418,24 @@ mono_type_get_name_recurse (MonoType *type, GString *str, gboolean is_recursed,
mono_type_name_check_byref (type, str);
break;
case MONO_TYPE_FNPTR: {
MonoTypeNameFormat nested_format;
nested_format = format == MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED ?
MONO_TYPE_NAME_FORMAT_FULL_NAME : format;
mono_type_get_name_recurse (type->data.method->ret, str, FALSE, nested_format);
g_string_append_c (str, '(');
for (int i = 0; i < type->data.method->param_count; ++i) {
mono_type_get_name_recurse (type->data.method->params[i], str, FALSE, nested_format);
if (i != type->data.method->param_count - 1)
g_string_append (str, ", ");
}
g_string_append_c (str, ')');
break;
}
default:
klass = mono_class_from_mono_type_internal (type);
if (m_class_get_nested_in (klass)) {
......
......@@ -215,6 +215,10 @@ ICALL_EXPORT MonoBoolean ves_icall_RuntimeTypeHandle_IsGenericTypeDefinition (Mo
ICALL_EXPORT gint32 ves_icall_RuntimeType_GetGenericParameterPosition (MonoQCallTypeHandle type_handle);
ICALL_EXPORT gint8 ves_icall_RuntimeType_GetCallingConventionFromFunctionPointerInternal (MonoQCallTypeHandle type_handle);
ICALL_EXPORT MonoBoolean ves_icall_RuntimeType_IsUnmanagedFunctionPointerInternal (MonoQCallTypeHandle type_handle);
ICALL_EXPORT int ves_icall_System_Enum_InternalGetCorElementType (MonoQCallTypeHandle type_handle);
ICALL_EXPORT gint32 ves_icall_System_Array_GetCorElementTypeOfElementTypeInternal (MonoObjectHandleOnStack arr_handle);
......
......@@ -384,7 +384,7 @@ ICALL_TYPE(MFIELD, "System.Reflection.RuntimeFieldInfo", MFIELD_1)
HANDLES(MFIELD_1, "GetFieldOffset", ves_icall_RuntimeFieldInfo_GetFieldOffset, gint32, 1, (MonoReflectionField))
HANDLES(MFIELD_2, "GetParentType", ves_icall_RuntimeFieldInfo_GetParentType, MonoReflectionType, 2, (MonoReflectionField, MonoBoolean))
HANDLES(MFIELD_3, "GetRawConstantValue", ves_icall_RuntimeFieldInfo_GetRawConstantValue, MonoObject, 1, (MonoReflectionField))
HANDLES(MFIELD_4, "GetTypeModifiers", ves_icall_System_Reflection_FieldInfo_GetTypeModifiers, MonoArray, 2, (MonoReflectionField, MonoBoolean))
HANDLES(MFIELD_4, "GetTypeModifiers", ves_icall_System_Reflection_FieldInfo_GetTypeModifiers, MonoArray, 3, (MonoReflectionField, MonoBoolean, int))
HANDLES(MFIELD_5, "GetValueInternal", ves_icall_RuntimeFieldInfo_GetValueInternal, MonoObject, 2, (MonoReflectionField, MonoObject))
HANDLES(MFIELD_6, "ResolveType", ves_icall_RuntimeFieldInfo_ResolveType, MonoReflectionType, 1, (MonoReflectionField))
HANDLES(MFIELD_7, "SetValueInternal", ves_icall_RuntimeFieldInfo_SetValueInternal, void, 3, (MonoReflectionField, MonoObject, MonoObject))
......@@ -421,10 +421,10 @@ HANDLES(MODULE_13, "get_MetadataToken", ves_icall_reflection_get_token, guint32,
ICALL_TYPE(PARAMI, "System.Reflection.RuntimeParameterInfo", MPARAMI_1)
HANDLES_REUSE_WRAPPER(MPARAMI_1, "GetMetadataToken", ves_icall_reflection_get_token)
HANDLES(MPARAMI_2, "GetTypeModifiers", ves_icall_RuntimeParameterInfo_GetTypeModifiers, MonoArray, 4, (MonoReflectionType, MonoObject, int, MonoBoolean))
HANDLES(MPARAMI_2, "GetTypeModifiers", ves_icall_RuntimeParameterInfo_GetTypeModifiers, MonoArray, 5, (MonoReflectionType, MonoObject, int, MonoBoolean, int))
ICALL_TYPE(MPROP, "System.Reflection.RuntimePropertyInfo", MPROP_1)
HANDLES(MPROP_1, "GetTypeModifiers", ves_icall_RuntimePropertyInfo_GetTypeModifiers, MonoArray, 2, (MonoReflectionProperty, MonoBoolean))
HANDLES(MPROP_1, "GetTypeModifiers", ves_icall_RuntimePropertyInfo_GetTypeModifiers, MonoArray, 3, (MonoReflectionProperty, MonoBoolean, int))
HANDLES(MPROP_2, "get_default_value", ves_icall_property_info_get_default_value, MonoObject, 1, (MonoReflectionProperty))
HANDLES_REUSE_WRAPPER(MPROP_3, "get_metadata_token", ves_icall_reflection_get_token)
HANDLES(MPROP_4, "get_property_info", ves_icall_RuntimePropertyInfo_get_property_info, void, 3, (MonoReflectionProperty, MonoPropertyInfo_ref, PInfo))
......@@ -492,12 +492,15 @@ HANDLES(MAHN_2, "ReboxToNullable", ves_icall_RuntimeMethodHandle_ReboxToNullable
ICALL_TYPE(RT, "System.RuntimeType", RT_31)
HANDLES(RT_31, "AllocateValueType", ves_icall_System_RuntimeType_AllocateValueType, void, 3, (MonoQCallTypeHandle, MonoObject, MonoObjectHandleOnStack))
HANDLES(RT_1, "CreateInstanceInternal", ves_icall_System_RuntimeType_CreateInstanceInternal, MonoObject, 1, (MonoQCallTypeHandle))
HANDLES(RT_28, "FunctionPointerReturnAndParameterTypes", ves_icall_RuntimeType_FunctionPointerReturnAndParameterTypes, GPtrArray_ptr, 1, (MonoQCallTypeHandle))
NOHANDLES(ICALL(RT_33, "GetCallingConventionFromFunctionPointerInternal", ves_icall_RuntimeType_GetCallingConventionFromFunctionPointerInternal))
HANDLES(RT_2, "GetConstructors_native", ves_icall_RuntimeType_GetConstructors_native, GPtrArray_ptr, 2, (MonoQCallTypeHandle, guint32))
HANDLES(RT_30, "GetCorrespondingInflatedMethod", ves_icall_RuntimeType_GetCorrespondingInflatedMethod, MonoReflectionMethod, 2, (MonoQCallTypeHandle, MonoReflectionMethod))
HANDLES(RT_21, "GetDeclaringMethod", ves_icall_RuntimeType_GetDeclaringMethod, void, 2, (MonoQCallTypeHandle, MonoObjectHandleOnStack))
HANDLES(RT_22, "GetDeclaringType", ves_icall_RuntimeType_GetDeclaringType, void, 2, (MonoQCallTypeHandle, MonoObjectHandleOnStack))
HANDLES(RT_3, "GetEvents_native", ves_icall_RuntimeType_GetEvents_native, GPtrArray_ptr, 3, (MonoQCallTypeHandle, char_ptr, guint32))
HANDLES(RT_5, "GetFields_native", ves_icall_RuntimeType_GetFields_native, GPtrArray_ptr, 4, (MonoQCallTypeHandle, char_ptr, guint32, guint32))
HANDLES(RT_32, "GetFunctionPointerTypeModifiers", ves_icall_RuntimeType_GetFunctionPointerTypeModifiers, MonoArray, 3, (MonoQCallTypeHandle, gint32, MonoBoolean))
HANDLES(RT_6, "GetGenericArgumentsInternal", ves_icall_RuntimeType_GetGenericArgumentsInternal, void, 3, (MonoQCallTypeHandle, MonoObjectHandleOnStack, MonoBoolean))
NOHANDLES(ICALL(RT_9, "GetGenericParameterPosition", ves_icall_RuntimeType_GetGenericParameterPosition))
HANDLES(RT_10, "GetInterfaceMapData", ves_icall_RuntimeType_GetInterfaceMapData, void, 4, (MonoQCallTypeHandle, MonoQCallTypeHandle, MonoArrayOut, MonoArrayOut))
......@@ -508,6 +511,7 @@ HANDLES(RT_24, "GetNamespace", ves_icall_RuntimeType_GetNamespace, void, 2, (Mon
HANDLES(RT_13, "GetNestedTypes_native", ves_icall_RuntimeType_GetNestedTypes_native, GPtrArray_ptr, 4, (MonoQCallTypeHandle, char_ptr, guint32, guint32))
HANDLES(RT_14, "GetPacking", ves_icall_RuntimeType_GetPacking, void, 3, (MonoQCallTypeHandle, guint32_ref, guint32_ref))
HANDLES(RT_15, "GetPropertiesByName_native", ves_icall_RuntimeType_GetPropertiesByName_native, GPtrArray_ptr, 4, (MonoQCallTypeHandle, char_ptr, guint32, guint32))
NOHANDLES(ICALL(RT_29, "IsUnmanagedFunctionPointerInternal", ves_icall_RuntimeType_IsUnmanagedFunctionPointerInternal))
HANDLES(RT_17, "MakeGenericType", ves_icall_RuntimeType_MakeGenericType, void, 3, (MonoReflectionType, MonoArray, MonoObjectHandleOnStack))
HANDLES(RT_19, "getFullName", ves_icall_System_RuntimeType_getFullName, void, 4, (MonoQCallTypeHandle, MonoObjectHandleOnStack, MonoBoolean, MonoBoolean))
HANDLES(RT_26, "make_array_type", ves_icall_RuntimeType_make_array_type, void, 3, (MonoQCallTypeHandle, int, MonoObjectHandleOnStack))
......
......@@ -1906,6 +1906,9 @@ ves_icall_RuntimeTypeHandle_GetMetadataToken (MonoQCallTypeHandle type_handle, M
{
MonoType *type = type_handle.type;
if (type->type == MONO_TYPE_FNPTR)
return MONO_TOKEN_TYPE_DEF; // coreCLR expects 0x02000000 as the metadata token value for function pointers
MonoClass *mc = mono_class_from_mono_type_internal (type);
if (!mono_class_init_internal (mc)) {
mono_error_set_for_class_failure (error, mc);
......@@ -2009,14 +2012,25 @@ ves_icall_System_Reflection_RuntimePropertyInfo_internal_from_handle_type (MonoP
return mono_property_get_object_handle (klass, handle, error);
}
static MonoType*
get_generic_argument_type (MonoType* type, unsigned int generic_argument_position)
{
g_assert (type->type == MONO_TYPE_GENERICINST);
g_assert (type->data.generic_class->context.class_inst->type_argc > generic_argument_position);
return type->data.generic_class->context.class_inst->type_argv [generic_argument_position];
}
MonoArrayHandle
ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionFieldHandle field_h, MonoBoolean optional, MonoError *error)
ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionFieldHandle field_h, MonoBoolean optional, int generic_argument_position, MonoError *error)
{
MonoClassField *field = MONO_HANDLE_GETVAL (field_h, field);
MonoType *type = mono_field_get_type_checked (field, error);
return_val_if_nok (error, NULL_HANDLE_ARRAY);
if (generic_argument_position > -1)
type = get_generic_argument_type (type, (unsigned int)generic_argument_position);
return type_array_from_modifiers (type, optional, error);
}
......@@ -2807,6 +2821,22 @@ ves_icall_RuntimeType_GetPacking (MonoQCallTypeHandle type_handle, guint32 *pack
}
}
gint8
ves_icall_RuntimeType_GetCallingConventionFromFunctionPointerInternal (MonoQCallTypeHandle type_handle)
{
MonoType *type = type_handle.type;
g_assert (type->type == MONO_TYPE_FNPTR);
// FIXME: Once we address: https://github.com/dotnet/runtime/issues/90308 this should not be needed anymore
return type->data.method->suppress_gc_transition ? MONO_CALL_UNMANAGED_MD : type->data.method->call_convention;
}
MonoBoolean
ves_icall_RuntimeType_IsUnmanagedFunctionPointerInternal (MonoQCallTypeHandle type_handle)
{
MonoType *type = type_handle.type;
return type->type == MONO_TYPE_FNPTR && type->data.method->pinvoke;
}
void
ves_icall_RuntimeTypeHandle_GetElementType (MonoQCallTypeHandle type_handle, MonoObjectHandleOnStack res, MonoError *error)
{
......@@ -2886,6 +2916,36 @@ ves_icall_RuntimeTypeHandle_IsByRefLike (MonoQCallTypeHandle type_handle, MonoEr
return !!m_class_is_byreflike (klass);
}
GPtrArray*
ves_icall_RuntimeType_FunctionPointerReturnAndParameterTypes (MonoQCallTypeHandle type_handle, MonoError *error)
{
// FIXME: cache - possible on managed side
MonoType *type = type_handle.type;
GPtrArray *res_array = g_ptr_array_new ();
g_ptr_array_add (res_array, type->data.method->ret);
for (int i = 0; i < type->data.method->param_count; ++i)
g_ptr_array_add (res_array, type->data.method->params[i]);
return res_array;
}
MonoArrayHandle
ves_icall_RuntimeType_GetFunctionPointerTypeModifiers (MonoQCallTypeHandle type_handle, int position, MonoBoolean optional, MonoError *error)
{
MonoType *type = type_handle.type;
g_assert (type->type == MONO_TYPE_FNPTR);
if (position == 0) {
return type_array_from_modifiers (type->data.method->ret, optional, error);
}
else {
g_assert (type->data.method->param_count > position - 1);
return type_array_from_modifiers (type->data.method->params[position - 1], optional, error);
}
}
MonoBoolean
ves_icall_RuntimeTypeHandle_IsComObject (MonoQCallTypeHandle type_handle, MonoError *error)
{
......@@ -2972,15 +3032,15 @@ ves_icall_RuntimeType_GetName (MonoQCallTypeHandle type_handle, MonoObjectHandle
MonoClass *klass = mono_class_from_mono_type_internal (type);
// FIXME: this should be escaped in some scenarios with mono_identifier_escape_type_name_chars
// Determining exactly when to do so is fairly difficult, so for now we don't bother to avoid regressions
const char *klass_name = m_class_get_name (klass);
const char *name = type->type == MONO_TYPE_FNPTR ? "" : m_class_get_name (klass);
if (m_type_is_byref (type)) {
char *n = g_strdup_printf ("%s&", klass_name);
char *n = g_strdup_printf ("%s&", name);
HANDLE_ON_STACK_SET (res, mono_string_new_checked (n, error));
g_free (n);
} else {
HANDLE_ON_STACK_SET (res, mono_string_new_checked (klass_name, error));
HANDLE_ON_STACK_SET (res, mono_string_new_checked (name, error));
}
}
......@@ -2988,8 +3048,10 @@ void
ves_icall_RuntimeType_GetNamespace (MonoQCallTypeHandle type_handle, MonoObjectHandleOnStack res, MonoError *error)
{
MonoType *type = type_handle.type;
if (type->type == MONO_TYPE_FNPTR)
return;
MonoClass *klass = mono_class_from_mono_type_internal (type);
MonoClass *elem;
while (!m_class_is_enumtype (klass) &&
!mono_class_is_nullable (klass) &&
......@@ -5084,7 +5146,7 @@ ves_icall_System_RuntimeType_getFullName (MonoQCallTypeHandle type_handle, MonoO
if (!name)
return;
if (full_name && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
if (full_name && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR || type->type == MONO_TYPE_FNPTR)) {
g_free (name);
return;
}
......@@ -6492,7 +6554,7 @@ fail:
}
MonoArrayHandle
ves_icall_RuntimeParameterInfo_GetTypeModifiers (MonoReflectionTypeHandle rt, MonoObjectHandle member, int pos, MonoBoolean optional, MonoError *error)
ves_icall_RuntimeParameterInfo_GetTypeModifiers (MonoReflectionTypeHandle rt, MonoObjectHandle member, int position, MonoBoolean optional, int generic_argument_position, MonoError *error)
{
MonoType *type = MONO_HANDLE_GETVAL (rt, type);
MonoClass *member_class = mono_handle_class (member);
......@@ -6514,10 +6576,13 @@ ves_icall_RuntimeParameterInfo_GetTypeModifiers (MonoReflectionTypeHandle rt, Mo
}
sig = mono_method_signature_internal (method);
if (pos == -1)
if (position == -1)
type = sig->ret;
else
type = sig->params [pos];
type = sig->params [position];
if (generic_argument_position > -1)
type = get_generic_argument_type (type, (unsigned int)generic_argument_position);
return type_array_from_modifiers (type, optional, error);
}
......@@ -6537,13 +6602,17 @@ get_property_type (MonoProperty *prop)
}
MonoArrayHandle
ves_icall_RuntimePropertyInfo_GetTypeModifiers (MonoReflectionPropertyHandle property, MonoBoolean optional, MonoError *error)
ves_icall_RuntimePropertyInfo_GetTypeModifiers (MonoReflectionPropertyHandle property, MonoBoolean optional, int generic_argument_position, MonoError *error)
{
MonoProperty *prop = MONO_HANDLE_GETVAL (property, property);
MonoType *type = get_property_type (prop);
if (!type)
return NULL_HANDLE_ARRAY;
if (generic_argument_position > -1)
type = get_generic_argument_type (type, (unsigned int)generic_argument_position);
return type_array_from_modifiers (type, optional, error);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册