- Added new public APIs FieldInfo.__FieldMarshal and ParameterInfo.__FieldMarshal.

- Moved ParameterInfo pseudo custom attribute handling to CustomAttributeData.
- Ignore HasFieldMarshal attribute and always return the pseudo custom attribute if a FieldMarshal record exists. This is similar to .NET reflection.
This commit is contained in:
jfrijters 2012-07-12 15:10:58 +00:00
Родитель d16815e89b
Коммит 2f91e4253b
13 изменённых файлов: 137 добавлений и 49 удалений

Просмотреть файл

@ -692,7 +692,7 @@ namespace IKVM.Reflection
public static IList<CustomAttributeData> GetCustomAttributes(ParameterInfo parameter)
{
return parameter.GetCustomAttributesData(null);
return __GetCustomAttributes(parameter, null, false);
}
public static IList<CustomAttributeData> __GetCustomAttributes(Assembly assembly, Type attributeType, bool inherit)
@ -707,7 +707,16 @@ namespace IKVM.Reflection
public static IList<CustomAttributeData> __GetCustomAttributes(ParameterInfo parameter, Type attributeType, bool inherit)
{
return parameter.GetCustomAttributesData(attributeType);
List<CustomAttributeData> list = parameter.Module.GetCustomAttributes(parameter.MetadataToken, attributeType);
if (attributeType == null || attributeType.IsAssignableFrom(parameter.Module.universe.System_Runtime_InteropServices_MarshalAsAttribute))
{
FieldMarshal spec = parameter.__FieldMarshal;
if (spec != null)
{
list.Add(spec.ToCustomAttribute(parameter.Module));
}
}
return list;
}
public static IList<CustomAttributeData> __GetCustomAttributes(MemberInfo member, Type attributeType, bool inherit)

Просмотреть файл

@ -99,6 +99,11 @@ namespace IKVM.Reflection.Emit
get { throw new NotImplementedException(); }
}
public override FieldMarshal __FieldMarshal
{
get { throw new NotImplementedException(); }
}
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute));
@ -114,7 +119,7 @@ namespace IKVM.Reflection.Emit
}
else if (customBuilder.Constructor.DeclaringType == u.System_Runtime_InteropServices_MarshalAsAttribute)
{
MarshalSpec.SetMarshalAsAttribute(typeBuilder.ModuleBuilder, pseudoToken, customBuilder);
FieldMarshal.SetMarshalAsAttribute(typeBuilder.ModuleBuilder, pseudoToken, customBuilder);
attribs |= FieldAttributes.HasFieldMarshal;
}
else if (customBuilder.Constructor.DeclaringType == u.System_NonSerializedAttribute)

Просмотреть файл

@ -515,6 +515,11 @@ namespace IKVM.Reflection.Emit
return method.customModifiers.GetParameterCustomModifiers(parameter);
}
public override FieldMarshal __FieldMarshal
{
get { return null; }
}
public override MemberInfo Member
{
get { return method; }

Просмотреть файл

@ -111,7 +111,7 @@ namespace IKVM.Reflection.Emit
}
else if (customAttributeBuilder.Constructor.DeclaringType == u.System_Runtime_InteropServices_MarshalAsAttribute)
{
MarshalSpec.SetMarshalAsAttribute(moduleBuilder, PseudoToken, customAttributeBuilder);
FieldMarshal.SetMarshalAsAttribute(moduleBuilder, PseudoToken, customAttributeBuilder);
flags |= (short)ParameterAttributes.HasFieldMarshal;
}
else

Просмотреть файл

@ -43,6 +43,7 @@ namespace IKVM.Reflection
public abstract void __GetDataFromRVA(byte[] data, int offset, int length);
public abstract int __FieldRVA { get; }
public abstract int __FieldOffset { get; }
public abstract FieldMarshal __FieldMarshal { get; }
public abstract Object GetRawConstantValue();
internal abstract FieldSignature FieldSignature { get; }
@ -189,6 +190,11 @@ namespace IKVM.Reflection
get { return field.__FieldOffset; }
}
public override FieldMarshal __FieldMarshal
{
get { return field.__FieldMarshal; }
}
public override Object GetRawConstantValue()
{
return field.GetRawConstantValue();

Просмотреть файл

@ -340,6 +340,11 @@ namespace IKVM.Reflection
get { return field.__FieldOffset; }
}
public override FieldMarshal __FieldMarshal
{
get { return field.__FieldMarshal; }
}
public override FieldInfo __GetFieldOnTypeDefinition()
{
return field;
@ -407,6 +412,11 @@ namespace IKVM.Reflection
return parameterInfo.__GetCustomModifiers().Bind(method);
}
public override FieldMarshal __FieldMarshal
{
get { return parameterInfo.__FieldMarshal; }
}
public override MemberInfo Member
{
get { return method; }

Просмотреть файл

@ -32,7 +32,7 @@ using IKVM.Reflection.Metadata;
namespace IKVM.Reflection
{
sealed class MarshalSpec
public sealed class FieldMarshal
{
private const UnmanagedType NATIVE_TYPE_MAX = (UnmanagedType)0x50;
private readonly UnmanagedType unmanagedType;
@ -46,7 +46,57 @@ namespace IKVM.Reflection
private readonly string marshalCookie;
private readonly Type marshalTypeRef;
private MarshalSpec(UnmanagedType unmanagedType, UnmanagedType? arraySubType, short? sizeParamIndex,
public UnmanagedType UnmanagedType
{
get { return unmanagedType; }
}
public UnmanagedType? ArraySubType
{
get { return arraySubType; }
}
public short? SizeParamIndex
{
get { return sizeParamIndex; }
}
public int? SizeConst
{
get { return sizeConst; }
}
public VarEnum? SafeArraySubType
{
get { return safeArraySubType; }
}
public Type SafeArrayUserDefinedSubType
{
get { return safeArrayUserDefinedSubType; }
}
public int? IidParameterIndex
{
get { return iidParameterIndex; }
}
public string MarshalType
{
get { return marshalType; }
}
public string MarshalCookie
{
get { return marshalCookie; }
}
public Type MarshalTypeRef
{
get { return marshalTypeRef; }
}
private FieldMarshal(UnmanagedType unmanagedType, UnmanagedType? arraySubType, short? sizeParamIndex,
int? sizeConst, VarEnum? safeArraySubType, Type safeArrayUserDefinedSubType, int? iidParameterIndex,
string marshalType, string marshalCookie, Type marshalTypeRef)
{
@ -62,7 +112,7 @@ namespace IKVM.Reflection
this.marshalTypeRef = marshalTypeRef;
}
internal static MarshalSpec ReadFieldMarshal(Module module, int token)
internal static FieldMarshal ReadFieldMarshal(Module module, int token)
{
foreach (int i in module.FieldMarshal.Filter(token))
{
@ -142,23 +192,13 @@ namespace IKVM.Reflection
marshalTypeRef = parser.GetType(module.universe, module.Assembly, false, marshalType, false, false);
}
}
return new MarshalSpec(unmanagedType, arraySubType, sizeParamIndex, sizeConst, safeArraySubType,
return new FieldMarshal(unmanagedType, arraySubType, sizeParamIndex, sizeConst, safeArraySubType,
safeArrayUserDefinedSubType, iidParameterIndex, marshalType, marshalCookie, marshalTypeRef);
}
return null;
}
internal static CustomAttributeData GetMarshalAsAttribute(Module module, int token)
{
MarshalSpec spec = ReadFieldMarshal(module, token);
if (spec != null)
{
return spec.ToCustomAttribute(module);
}
throw new BadImageFormatException();
}
private CustomAttributeData ToCustomAttribute(Module module)
internal CustomAttributeData ToCustomAttribute(Module module)
{
Type typeofMarshalAs = module.universe.System_Runtime_InteropServices_MarshalAsAttribute;
Type typeofUnmanagedType = module.universe.System_Runtime_InteropServices_UnmanagedType;

Просмотреть файл

@ -730,6 +730,11 @@ namespace IKVM.Reflection
: method.signature.GetParameterCustomModifiers(method, index);
}
public override FieldMarshal __FieldMarshal
{
get { return Forwarder.__FieldMarshal; }
}
public override MemberInfo Member
{
get { return method; }
@ -745,11 +750,6 @@ namespace IKVM.Reflection
get { return method.Module; }
}
internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
{
return Forwarder.GetCustomAttributesData(attributeType);
}
public override string ToString()
{
return Forwarder.ToString();
@ -980,6 +980,11 @@ namespace IKVM.Reflection
get { return Forwarder.__FieldOffset; }
}
public override FieldMarshal __FieldMarshal
{
get { return Forwarder.__FieldMarshal; }
}
public override object GetRawConstantValue()
{
return Forwarder.GetRawConstantValue();

Просмотреть файл

@ -59,6 +59,7 @@ namespace IKVM.Reflection
public abstract int Position { get; }
public abstract object RawDefaultValue { get; }
public abstract CustomModifiers __GetCustomModifiers();
public abstract FieldMarshal __FieldMarshal { get; }
public abstract MemberInfo Member { get; }
public abstract int MetadataToken { get; }
internal abstract Module Module { get; }
@ -107,11 +108,6 @@ namespace IKVM.Reflection
{
return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit);
}
internal virtual IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
{
return this.Module.GetCustomAttributes(this.MetadataToken, attributeType);
}
}
sealed class ParameterInfoWrapper : ParameterInfo
@ -155,6 +151,11 @@ namespace IKVM.Reflection
return forward.__GetCustomModifiers();
}
public override FieldMarshal __FieldMarshal
{
get { return forward.__FieldMarshal; }
}
public override MemberInfo Member
{
get { return member; }
@ -169,10 +170,5 @@ namespace IKVM.Reflection
{
get { return member.Module; }
}
internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
{
return forward.GetCustomAttributesData(attributeType);
}
}
}

Просмотреть файл

@ -91,6 +91,11 @@ namespace IKVM.Reflection
return property.PropertySignature.GetParameterCustomModifiers(parameter);
}
public override FieldMarshal __FieldMarshal
{
get { return null; }
}
public override MemberInfo Member
{
get { return property; }

Просмотреть файл

@ -114,13 +114,21 @@ namespace IKVM.Reflection.Reader
}
}
public override FieldMarshal __FieldMarshal
{
get { return FieldMarshal.ReadFieldMarshal(module, this.MetadataToken); }
}
internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
{
List<CustomAttributeData> list = module.GetCustomAttributes(this.MetadataToken, attributeType);
if ((this.Attributes & FieldAttributes.HasFieldMarshal) != 0
&& (attributeType == null || attributeType.IsAssignableFrom(module.universe.System_Runtime_InteropServices_MarshalAsAttribute)))
if (attributeType == null || attributeType.IsAssignableFrom(module.universe.System_Runtime_InteropServices_MarshalAsAttribute))
{
list.Add(MarshalSpec.GetMarshalAsAttribute(module, this.MetadataToken));
FieldMarshal spec = FieldMarshal.ReadFieldMarshal(module, this.MetadataToken);
if (spec != null)
{
list.Add(spec.ToCustomAttribute(module));
}
}
if (declaringType.IsExplicitLayout
&& (attributeType == null || attributeType.IsAssignableFrom(module.universe.System_Runtime_InteropServices_FieldOffsetAttribute)))

Просмотреть файл

@ -433,7 +433,7 @@ namespace IKVM.Reflection.Reader
Type attr = universe.System_Runtime_CompilerServices_DecimalConstantAttribute;
if (attr != null)
{
foreach (CustomAttributeData cad in GetCustomAttributesData(attr))
foreach (CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(this, attr, false))
{
IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
if (args.Count == 5)
@ -473,6 +473,11 @@ namespace IKVM.Reflection.Reader
: method.MethodSignature.GetParameterCustomModifiers(method, position);
}
public override FieldMarshal __FieldMarshal
{
get { return FieldMarshal.ReadFieldMarshal(this.Module, this.MetadataToken); }
}
public override MemberInfo Member
{
get
@ -496,16 +501,5 @@ namespace IKVM.Reflection.Reader
{
get { return method.Module; }
}
internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
{
IList<CustomAttributeData> list = base.GetCustomAttributesData(attributeType);
if ((this.Attributes & ParameterAttributes.HasFieldMarshal) != 0
&& (attributeType == null || attributeType.IsAssignableFrom(this.Module.universe.System_Runtime_InteropServices_MarshalAsAttribute)))
{
list.Add(MarshalSpec.GetMarshalAsAttribute(this.Module, this.MetadataToken));
}
return list;
}
}
}

Просмотреть файл

@ -2369,6 +2369,11 @@ namespace IKVM.Reflection
return new CustomModifiers();
}
public override FieldMarshal __FieldMarshal
{
get { return null; }
}
public override MemberInfo Member
{
get { return method.IsConstructor ? (MethodBase)new ConstructorInfoImpl(method) : method; }