Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ internal FieldOnTypeBuilderInstantiation(FieldInfo field, TypeBuilderInstantiati
#region Public Abstract\Virtual Members
public override Type[] GetRequiredCustomModifiers() { return _field.GetRequiredCustomModifiers(); }
public override Type[] GetOptionalCustomModifiers() { return _field.GetOptionalCustomModifiers(); }
public override Type GetModifiedFieldType() => _field.GetModifiedFieldType();
public override void SetValueDirect(TypedReference obj, object value)
{
throw new NotImplementedException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public override MethodInfo MakeGenericMethod(params Type[] typeArgs)

#region Public Abstract\Virtual Members
public override Type ReturnType => _method.ReturnType;
public override ParameterInfo ReturnParameter => throw new NotSupportedException();
public override ParameterInfo ReturnParameter => _method.ReturnParameter;
public override ICustomAttributeProvider ReturnTypeCustomAttributes => throw new NotSupportedException();
public override MethodInfo GetBaseDefinition() { throw new NotSupportedException(); }
#endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,10 @@ public override Type[] GetOptionalCustomModifiers()
public override bool IsEnum => _unmodifiedType.IsEnum;
protected override bool IsPrimitiveImpl() => _unmodifiedType.IsPrimitive;
protected override bool IsByRefImpl() => _unmodifiedType.IsByRef;
public override bool IsGenericParameter => _unmodifiedType.IsGenericParameter;
public override bool IsGenericTypeParameter => _unmodifiedType.IsGenericTypeParameter;
public override bool IsGenericMethodParameter => _unmodifiedType.IsGenericMethodParameter;
public override int GenericParameterPosition => _unmodifiedType.GenericParameterPosition;
protected override bool IsPointerImpl() => _unmodifiedType.IsPointer;
protected override bool IsValueTypeImpl() => _unmodifiedType.IsValueType;
protected override bool IsCOMObjectImpl() => _unmodifiedType.IsCOMObject;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ public override void SetValue(object? obj, object? val, BindingFlags invokeAttr,

public override Type[] GetOptionalCustomModifiers() => _optionalCustomModifiers ?? Type.EmptyTypes;

public override Type GetModifiedFieldType() => FieldType;

#endregion

#region ICustomAttributeProvider Implementation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ internal void AppendMetadata(MethodBodyStreamEncoder methodBodyEncoder, BlobBuil
}

// Now write all generic parameters in order
genericParams.Sort((x, y) => {
genericParams.Sort((x, y) =>
{
int primary = CodedIndex.TypeOrMethodDef(x._parentHandle).CompareTo(CodedIndex.TypeOrMethodDef(y._parentHandle));
if (primary != 0)
return primary;
Expand Down Expand Up @@ -690,6 +691,8 @@ internal void WriteCustomAttributes(List<CustomAttributeWrapper>? customAttribut

private EntityHandle GetTypeReferenceOrSpecificationHandle(Type type)
{
type = type.UnderlyingSystemType;

if (!_typeReferences.TryGetValue(type, out var typeHandle))
{
if (type.HasElementType || type.IsGenericParameter ||
Expand Down Expand Up @@ -740,7 +743,7 @@ private EntityHandle GetMemberReferenceHandle(MemberInfo memberInfo)
declaringType = declaringType.MakeGenericType(declaringType.GetGenericArguments());
}

Type fieldType = ((FieldInfo)GetOriginalMemberIfConstructedType(field)).FieldType;
Type fieldType = ((FieldInfo)GetOriginalMemberIfConstructedType(field)).GetModifiedFieldType();
memberHandle = AddMemberReference(field.Name, GetTypeHandle(declaringType),
MetadataSignatureHelper.GetFieldSignature(fieldType, field.GetRequiredCustomModifiers(), field.GetOptionalCustomModifiers(), this));

Expand Down Expand Up @@ -791,7 +794,7 @@ private EntityHandle GetMethodReference(MethodInfo methodInfo, Type[] optionalPa
}

private BlobBuilder GetMethodSignature(MethodInfo method, Type[]? optionalParameterTypes) =>
MetadataSignatureHelper.GetMethodSignature(this, ParameterTypes(method.GetParameters()), method.ReturnType,
MetadataSignatureHelper.GetMethodSignature(this, MetadataSignatureHelper.GetParameterTypes(method.GetParameters()), method.ReturnParameter.GetModifiedParameterType(),
GetSignatureConvention(method.CallingConvention), method.GetGenericArguments().Length, !method.IsStatic, optionalParameterTypes);

private BlobBuilder GetMethodArrayMethodSignature(ArrayMethod method) => MetadataSignatureHelper.GetMethodSignature(
Expand Down Expand Up @@ -829,23 +832,6 @@ private MemberInfo GetOriginalMemberIfConstructedType(MemberInfo memberInfo)
return memberInfo;
}

private static Type[] ParameterTypes(ParameterInfo[] parameterInfos)
{
if (parameterInfos.Length == 0)
{
return Type.EmptyTypes;
}

Type[] parameterTypes = new Type[parameterInfos.Length];

for (int i = 0; i < parameterInfos.Length; i++)
{
parameterTypes[i] = parameterInfos[i].ParameterType;
}

return parameterTypes;
}

private AssemblyReferenceHandle GetAssemblyReference(Assembly assembly)
{
if (!_assemblyReferences.TryGetValue(assembly, out var handle))
Expand All @@ -861,7 +847,7 @@ private AssemblyReferenceHandle GetAssemblyReference(Assembly assembly)
}
else
{
publicKeyOrToken = aName.GetPublicKeyToken();
publicKeyOrToken = aName.GetPublicKeyToken();
}
handle = AddAssemblyReference(aName.Name, aName.Version, aName.CultureName, publicKeyOrToken, assemblyFlags);
_assemblyReferences.Add(assembly, handle);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan
internal sealed class ParameterInfoWrapper : ParameterInfo
{
private readonly ParameterBuilderImpl _pb;
private readonly Type _type
;
private readonly Type _type;
public ParameterInfoWrapper(ParameterBuilderImpl pb, Type type)
{
_pb = pb;
Expand All @@ -87,5 +86,7 @@ public ParameterInfoWrapper(ParameterBuilderImpl pb, Type type)
public override bool HasDefaultValue => _pb._defaultValue != DBNull.Value;

public override object? DefaultValue => HasDefaultValue ? _pb._defaultValue : null;

public override Type GetModifiedParameterType() => ParameterType;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ internal static BlobBuilder GetConstructorSignature(ParameterInfo[]? parameters,

retType.Void();

WriteParametersSignature(module, Array.ConvertAll(parameters, p => p.ParameterType), parameterEncoder);
WriteParametersSignature(module, GetParameterTypes(parameters), parameterEncoder);

return constructorSignature;
}
Expand Down Expand Up @@ -106,6 +106,23 @@ internal static BlobBuilder GetMethodSignature(ModuleBuilderImpl module, Type[]?
return methodSignature;
}

internal static Type[] GetParameterTypes(ParameterInfo[] parameterInfos)
{
if (parameterInfos.Length == 0)
{
return Type.EmptyTypes;
}

Type[] parameterTypes = new Type[parameterInfos.Length];

for (int i = 0; i < parameterInfos.Length; i++)
{
parameterTypes[i] = parameterInfos[i].GetModifiedParameterType();
}

return parameterTypes;
}

private static void WriteReturnTypeCustomModifiers(CustomModifiersEncoder encoder,
Type[]? requiredModifiers, Type[]? optionalModifiers, ModuleBuilderImpl module)
{
Expand All @@ -122,8 +139,10 @@ private static void WriteReturnTypeCustomModifiers(CustomModifiersEncoder encode

private static void WriteCustomModifiers(CustomModifiersEncoder encoder, Type[] customModifiers, bool isOptional, ModuleBuilderImpl module)
{
foreach (Type modifier in customModifiers)
// GetOptionalCustomModifiers and GetRequiredCustomModifiers return modifiers in reverse order
for (int i = customModifiers.Length - 1; i >= 0; i--)
{
Type modifier = customModifiers[i];
encoder.AddModifier(module.GetTypeHandle(modifier), isOptional);
}
}
Expand Down Expand Up @@ -295,6 +314,7 @@ private static void WriteSignatureForFunctionPointerType(SignatureTypeEncoder si

private static void WriteSimpleSignature(SignatureTypeEncoder signature, Type type, ModuleBuilderImpl module)
{
type = type.UnderlyingSystemType;
CoreTypeId? typeId = module.GetTypeIdFromCoreTypes(type);

switch (typeId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -633,13 +633,13 @@ public void ReturnTypeAndParameterRequiredOptionalCustomModifiers()
Type[] par0RequiredMods = allModMethod.GetParameters()[0].GetRequiredCustomModifiers();
Type[] par0OptionalMods = allModMethod.GetParameters()[0].GetOptionalCustomModifiers();
Assert.Equal(2, returnReqMods.Length);
Assert.Equal(mlc.CoreAssembly.GetType(typeof(short).FullName), returnReqMods[0]);
Assert.Equal(mlc.CoreAssembly.GetType(typeof(int).FullName), returnReqMods[1]);
Assert.Equal(mlc.CoreAssembly.GetType(typeof(int).FullName), returnReqMods[0]);
Assert.Equal(mlc.CoreAssembly.GetType(typeof(short).FullName), returnReqMods[1]);
Assert.Equal(1, returnOptMods.Length);
Assert.Equal(mlc.CoreAssembly.GetType(typeof(Version).FullName), returnOptMods[0]);
Assert.Equal(cmodsReq1.Length, par0RequiredMods.Length);
Assert.Equal(mlc.CoreAssembly.GetType(cmodsReq1[1].FullName), par0RequiredMods[0]);
Assert.Equal(mlc.CoreAssembly.GetType(cmodsReq1[0].FullName), par0RequiredMods[1]);
Assert.Equal(mlc.CoreAssembly.GetType(cmodsReq1[0].FullName), par0RequiredMods[0]);
Assert.Equal(mlc.CoreAssembly.GetType(cmodsReq1[1].FullName), par0RequiredMods[1]);
Assert.Equal(cmodsOpt1.Length, par0OptionalMods.Length);
Assert.Equal(mlc.CoreAssembly.GetType(cmodsOpt1[0].FullName), par0OptionalMods[0]);
Assert.Equal(cmodsReq2.Length, allModMethod.GetParameters()[1].GetRequiredCustomModifiers().Length);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -864,7 +864,8 @@ public void SaveFunctionPointerFields()
}

[Fact]
public void ConsumeFunctionPointerFields()
[ActiveIssue("https://github.com/dotnet/runtime/issues/2383", TestRuntimes.Mono)]
public void ConsumeFunctionPointerMembers()
{
// public unsafe class Container
// {
Expand Down Expand Up @@ -915,16 +916,29 @@ public void ConsumeFunctionPointerFields()
MethodBuilder mainMethod = programType.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static);
mainMethod.SetReturnType(typeof(int));
ILGenerator il = mainMethod.GetILGenerator();
il.Emit(OpCodes.Ldsfld, typeof(ClassWithFunctionPointerFields).GetField("field1"));
il.Emit(OpCodes.Ldsfld, typeof(ClassWithFunctionPointerMembers).GetField("field1"));
il.Emit(OpCodes.Pop);
il.Emit(OpCodes.Ldsfld, typeof(ClassWithFunctionPointerMembers).GetField("field2"));
il.Emit(OpCodes.Pop);
il.Emit(OpCodes.Ldsfld, typeof(ClassWithFunctionPointerMembers).GetField("field3"));
il.Emit(OpCodes.Pop);
il.Emit(OpCodes.Ldsfld, typeof(ClassWithFunctionPointerMembers).GetField("field4"));
il.Emit(OpCodes.Pop);
il.Emit(OpCodes.Ldsfld, typeof(ClassWithFunctionPointerMembers).GetField("field5"));
il.Emit(OpCodes.Pop);
il.Emit(OpCodes.Call, typeof(ClassWithFunctionPointerMembers).GetMethod("Method1"));
il.Emit(OpCodes.Pop);
il.Emit(OpCodes.Call, typeof(ClassWithFunctionPointerMembers).GetMethod("Method2"));
il.Emit(OpCodes.Pop);
il.Emit(OpCodes.Call, typeof(ClassWithFunctionPointerMembers).GetMethod("Method3"));
il.Emit(OpCodes.Pop);
il.Emit(OpCodes.Call, typeof(ClassWithFunctionPointerMembers).GetMethod("Method4"));
il.Emit(OpCodes.Call, typeof(ClassWithFunctionPointerMembers).GetMethod("Method5"));
il.Emit(OpCodes.Pop);
il.Emit(OpCodes.Ldsfld, typeof(GenericClassWithFunctionPointerMembers<int>).GetField("Field"));
il.Emit(OpCodes.Pop);
il.Emit(OpCodes.Call, typeof(GenericClassWithFunctionPointerMembers<Guid>).GetMethod("Method").MakeGenericMethod(typeof(string)));
il.Emit(OpCodes.Pop);
// References to fields with unmanaged calling convention are broken
// [ActiveIssue("https://github.com/dotnet/runtime/issues/120909")]
// il.Emit(OpCodes.Ldsfld, typeof(ClassWithFunctionPointerFields).GetField("field2"));
// il.Emit(OpCodes.Pop);
// il.Emit(OpCodes.Ldsfld, typeof(ClassWithFunctionPointerFields).GetField("field3"));
// il.Emit(OpCodes.Pop);
// il.Emit(OpCodes.Ldsfld, typeof(ClassWithFunctionPointerFields).GetField("field4"));
// il.Emit(OpCodes.Pop);
il.Emit(OpCodes.Call, assembly1FromDisk.GetType("Container").GetMethod("Init"));
il.Emit(OpCodes.Ldc_I4_2);
il.Emit(OpCodes.Ldc_I4_3);
Expand Down Expand Up @@ -989,11 +1003,24 @@ public class ClassWithFields : EmptyTestClass
public byte field2;
}

public unsafe class ClassWithFunctionPointerFields
public unsafe class ClassWithFunctionPointerMembers
{
public static delegate*<ClassWithFunctionPointerFields> field1;
public static delegate*<ClassWithFunctionPointerMembers> field1;
public static delegate* unmanaged<int> field2;
public static delegate* unmanaged[Cdecl]<Guid> field3;
public static delegate* unmanaged[Cdecl, SuppressGCTransition]<Vector<int>, Vector<int>> field4;
public static List<delegate* unmanaged[Stdcall, MemberFunction, SuppressGCTransition]<long>*[]> field5;

public static delegate*<int> Method1() => null;
public static delegate* unmanaged<string> Method2() => null;
public static delegate* unmanaged[Fastcall]<double> Method3() => null;
public static delegate* unmanaged[Cdecl]<delegate* unmanaged<int>, Guid> Method4() => null;
public static delegate* unmanaged[Cdecl]<int> Method5(delegate* unmanaged[Cdecl]<delegate* unmanaged<int>, Guid> funcPtr) => null;
}

public unsafe class GenericClassWithFunctionPointerMembers<T>
{
public static delegate* unmanaged[Cdecl]<T> Field;
public static delegate* unmanaged[Fastcall, MemberFunction]<T, U> Method<U>() => null;
}
}
Loading