Skip to content
Open
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 @@ -30,8 +30,7 @@ internal static BlobBuilder GetFieldSignature(Type fieldType, Type[] requiredCus
{
BlobBuilder fieldSignature = new();
FieldTypeEncoder encoder = new BlobEncoder(fieldSignature).Field();
WriteReturnTypeCustomModifiers(encoder.CustomModifiers(), requiredCustomModifiers, optionalCustomModifiers, module);
WriteSignatureForType(encoder.Type(), fieldType, module);
WriteSignatureForType(encoder.Type(), fieldType, module, requiredCustomModifiers, optionalCustomModifiers);

return fieldSignature;
}
Expand All @@ -48,7 +47,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 @@ -85,16 +84,8 @@ internal static BlobBuilder GetMethodSignature(ModuleBuilderImpl module, Type[]?
new BlobEncoder(methodSignature).MethodSignature(convention, genParamCount, isInstance).
Parameters(paramsLength, out ReturnTypeEncoder retEncoder, out ParametersEncoder parEncoder);

WriteReturnTypeCustomModifiers(retEncoder.CustomModifiers(), returnTypeRequiredModifiers, returnTypeOptionalModifiers, module);

if (returnType != null && returnType != module.GetTypeFromCoreAssembly(CoreTypeId.Void))
{
WriteSignatureForType(retEncoder.Type(), returnType, module);
}
else
{
retEncoder.Void();
}
returnType ??= module.GetTypeFromCoreAssembly(CoreTypeId.Void);
WriteSignatureForType(retEncoder.Type(), returnType, module, returnTypeRequiredModifiers, returnTypeOptionalModifiers);

WriteParametersSignature(module, parameters, parEncoder, parameterRequiredModifiers, parameterOptionalModifiers);

Expand All @@ -106,24 +97,29 @@ internal static BlobBuilder GetMethodSignature(ModuleBuilderImpl module, Type[]?
return methodSignature;
}

private static void WriteReturnTypeCustomModifiers(CustomModifiersEncoder encoder,
Type[]? requiredModifiers, Type[]? optionalModifiers, ModuleBuilderImpl module)
internal static Type[] GetParameterTypes(ParameterInfo[] parameterInfos)
{
if (requiredModifiers != null)
if (parameterInfos.Length == 0)
{
WriteCustomModifiers(encoder, requiredModifiers, isOptional: false, module);
return Type.EmptyTypes;
}

if (optionalModifiers != null)
Type[] parameterTypes = new Type[parameterInfos.Length];

for (int i = 0; i < parameterInfos.Length; i++)
{
WriteCustomModifiers(encoder, optionalModifiers, isOptional: true, module);
parameterTypes[i] = parameterInfos[i].GetModifiedParameterType();
}

return parameterTypes;
}

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 All @@ -137,17 +133,10 @@ private static void WriteParametersSignature(ModuleBuilderImpl module, Type[]? p
{
ParameterTypeEncoder encoder = parameterEncoder.AddParameter();

if (requiredModifiers != null && requiredModifiers.Length > i && requiredModifiers[i] != null)
{
WriteCustomModifiers(encoder.CustomModifiers(), requiredModifiers[i], isOptional: false, module);
}

if (optionalModifiers != null && optionalModifiers.Length > i && optionalModifiers[i] != null)
{
WriteCustomModifiers(encoder.CustomModifiers(), optionalModifiers[i], isOptional: true, module);
}
Type[]? modreqs = (requiredModifiers != null && requiredModifiers.Length > i) ? requiredModifiers[i] : null;
Type[]? modopts = (optionalModifiers != null && optionalModifiers.Length > i) ? optionalModifiers[i] : null;

WriteSignatureForType(encoder.Type(), parameters[i], module);
WriteSignatureForType(encoder.Type(), parameters[i], module, modreqs, modopts);
}
}
}
Expand All @@ -160,15 +149,16 @@ internal static BlobBuilder GetPropertySignature(PropertyBuilderImpl property, M
PropertySignature(isInstanceProperty: property.CallingConventions.HasFlag(CallingConventions.HasThis)).
Parameters(property.ParameterTypes == null ? 0 : property.ParameterTypes.Length, out ReturnTypeEncoder retType, out ParametersEncoder paramEncoder);

WriteReturnTypeCustomModifiers(retType.CustomModifiers(), property._returnTypeRequiredCustomModifiers, property._returnTypeOptionalCustomModifiers, module);
WriteSignatureForType(retType.Type(), property.PropertyType, module);
WriteSignatureForType(retType.Type(), property.PropertyType, module, property._returnTypeRequiredCustomModifiers, property._returnTypeOptionalCustomModifiers);
WriteParametersSignature(module, property.ParameterTypes, paramEncoder, property._parameterTypeRequiredCustomModifiers, property._parameterTypeOptionalCustomModifiers);

return propertySignature;
}

private static void WriteSignatureForType(SignatureTypeEncoder signature, Type type, ModuleBuilderImpl module)
private static void WriteSignatureForType(SignatureTypeEncoder signature, Type type, ModuleBuilderImpl module, Type[]? requiredModifiers = null, Type[]? optionalModifiers = null)
{
WriteCustomModifiers(signature.CustomModifiers(), requiredModifiers ?? type.GetRequiredCustomModifiers(), isOptional: false, module);
WriteCustomModifiers(signature.CustomModifiers(), optionalModifiers ?? type.GetOptionalCustomModifiers(), isOptional: true, module);
if (type.IsArray)
{
Type elementType = type.GetElementType()!;
Expand All @@ -180,8 +170,8 @@ private static void WriteSignatureForType(SignatureTypeEncoder signature, Type t
else
{
signature.Array(out SignatureTypeEncoder elTypeSignature, out ArrayShapeEncoder arrayEncoder);
WriteSimpleSignature(elTypeSignature, elementType, module);
arrayEncoder.Shape(type.GetArrayRank(), ImmutableArray.Create<int>(), ImmutableArray.Create<int>(new int[rank]));
WriteSignatureForType(elTypeSignature, elementType, module);
arrayEncoder.Shape(type.GetArrayRank(), [], default);
}
}
else if (type.IsPointer)
Expand Down Expand Up @@ -223,14 +213,64 @@ private static void WriteSignatureForType(SignatureTypeEncoder signature, Type t
{
signature.GenericTypeParameter(type.GenericParameterPosition);
}
else if (type.IsFunctionPointer)
{
WriteSignatureForFunctionPointerType(signature, type, module);
}
else
{
WriteSimpleSignature(signature, type, module);
}
}

private static void WriteSignatureForFunctionPointerType(SignatureTypeEncoder signature, Type type, ModuleBuilderImpl module)
{
SignatureCallingConvention callConv = SignatureCallingConvention.Default;
FunctionPointerAttributes attribs = FunctionPointerAttributes.None;

Type returnType = type.GetFunctionPointerReturnType();
Type[] paramTypes = type.GetFunctionPointerParameterTypes();

if (type.IsUnmanagedFunctionPointer)
{
callConv = SignatureCallingConvention.Unmanaged;

if (type.GetFunctionPointerCallingConventions() is Type[] conventions && conventions.Length == 1)
{
switch (conventions[0].FullName)
{
case "System.Runtime.CompilerServices.CallConvCdecl":
callConv = SignatureCallingConvention.CDecl;
break;
case "System.Runtime.CompilerServices.CallConvStdcall":
callConv = SignatureCallingConvention.StdCall;
break;
case "System.Runtime.CompilerServices.CallConvThiscall":
callConv = SignatureCallingConvention.ThisCall;
break;
case "System.Runtime.CompilerServices.CallConvFastcall":
callConv = SignatureCallingConvention.FastCall;
break;
}
}
}

MethodSignatureEncoder sigEncoder = signature.FunctionPointer(callConv, attribs);
sigEncoder.Parameters(paramTypes.Length, out ReturnTypeEncoder retTypeEncoder, out ParametersEncoder paramsEncoder);

WriteSignatureForType(retTypeEncoder.Type(), returnType, module);

foreach (Type paramType in paramTypes)
{
ParameterTypeEncoder paramEncoder = paramsEncoder.AddParameter();

WriteSignatureForType(paramEncoder.Type(), paramType, module);
}
}

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 @@ -2637,9 +2637,9 @@ public void ReferenceNestedGenericTypeWithConstructedTypeBuilderParameterInIL()
TypeBuilder nestedItem = type.DefineNestedType("ItemInfo", TypeAttributes.NestedPublic);
GenericTypeParameterBuilder itemParam = nestedItem.DefineGenericParameters(genParams)[0];
TypeBuilder nestedSector = type.DefineNestedType("Sector", TypeAttributes.NestedPublic);
GenericTypeParameterBuilder nestedParam = nestedSector.DefineGenericParameters(genParams)[0];
GenericTypeParameterBuilder sectorParam = nestedSector.DefineGenericParameters(genParams)[0];

Type nestedOfT = nestedItem.MakeGenericType(nestedParam);
Type nestedOfT = nestedItem.MakeGenericType(sectorParam);
Type parent = typeof(HashSet<>).MakeGenericType(nestedOfT);
nestedSector.SetParent(parent);

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
Loading
Loading