зеркало из https://github.com/mono/ikvm-fork.git
Add support for returning pseudo-custom attributes based on missing types.
This commit is contained in:
Родитель
f20cd45070
Коммит
68816bf709
|
@ -46,7 +46,7 @@ namespace IKVM.Reflection
|
|||
this.index = index;
|
||||
}
|
||||
|
||||
// this is for pseudo-custom attributes
|
||||
// this is for pseudo-custom attributes and CustomAttributeBuilder.ToData()
|
||||
internal CustomAttributeData(Module module, ConstructorInfo constructor, object[] args, List<CustomAttributeNamedArgument> namedArguments)
|
||||
{
|
||||
this.module = module;
|
||||
|
@ -148,11 +148,11 @@ namespace IKVM.Reflection
|
|||
ConstructorInfo constructor;
|
||||
if (type == u.System_Security_Permissions_HostProtectionAttribute && action == (int)System.Security.Permissions.SecurityAction.LinkDemand)
|
||||
{
|
||||
constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
|
||||
constructor = type.GetPseudoCustomAttributeConstructor();
|
||||
}
|
||||
else
|
||||
{
|
||||
constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { u.System_Security_Permissions_SecurityAction }, null);
|
||||
constructor = type.GetPseudoCustomAttributeConstructor(u.System_Security_Permissions_SecurityAction);
|
||||
}
|
||||
// LAMESPEC there is an additional length here (probably of the named argument list)
|
||||
ByteReader slice = br.Slice(br.ReadCompressedInt());
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2008, 2010 Jeroen Frijters
|
||||
Copyright (C) 2008-2011 Jeroen Frijters
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@ -112,7 +112,31 @@ namespace IKVM.Reflection
|
|||
blob.ReadCompressedInt();
|
||||
marshalType = ReadString(blob);
|
||||
marshalCookie = ReadString(blob);
|
||||
marshalTypeRef = module.Assembly.GetType(marshalType) ?? module.universe.GetType(marshalType);
|
||||
|
||||
// we have to use a custom type lookup scheme here, because we want to use FindType to avoid a MissingAssemblyException
|
||||
TypeNameParser parser = TypeNameParser.Parse(marshalType, false);
|
||||
if (!parser.Error)
|
||||
{
|
||||
TypeName n = TypeName.Split(parser.FirstNamePart);
|
||||
Type type = null;
|
||||
if (parser.AssemblyName != null)
|
||||
{
|
||||
Assembly asm = module.Assembly.universe.Load(parser.AssemblyName, module.Assembly, false);
|
||||
if (asm != null)
|
||||
{
|
||||
type = asm.FindType(n);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
type = module.Assembly.FindType(n)
|
||||
?? module.universe.Mscorlib.FindType(n);
|
||||
}
|
||||
if (type != null)
|
||||
{
|
||||
marshalTypeRef = parser.Expand(type, module.Assembly, false, marshalType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Type typeofMarshalAs = module.universe.System_Runtime_InteropServices_MarshalAsAttribute;
|
||||
|
@ -122,47 +146,57 @@ namespace IKVM.Reflection
|
|||
List<CustomAttributeNamedArgument> named = new List<CustomAttributeNamedArgument>();
|
||||
if (arraySubType != null)
|
||||
{
|
||||
named.Add(new CustomAttributeNamedArgument(typeofMarshalAs.GetField("ArraySubType"), new CustomAttributeTypedArgument(typeofUnmanagedType, arraySubType.Value)));
|
||||
AddNamedArgument(named, typeofMarshalAs, "ArraySubType", typeofUnmanagedType, arraySubType.Value);
|
||||
}
|
||||
if (sizeParamIndex != null)
|
||||
{
|
||||
named.Add(new CustomAttributeNamedArgument(typeofMarshalAs.GetField("SizeParamIndex"), new CustomAttributeTypedArgument(module.universe.System_Int16, sizeParamIndex.Value)));
|
||||
AddNamedArgument(named, typeofMarshalAs, "SizeParamIndex", module.universe.System_Int16, sizeParamIndex.Value);
|
||||
}
|
||||
if (sizeConst != null)
|
||||
{
|
||||
named.Add(new CustomAttributeNamedArgument(typeofMarshalAs.GetField("SizeConst"), new CustomAttributeTypedArgument(module.universe.System_Int32, sizeConst.Value)));
|
||||
AddNamedArgument(named, typeofMarshalAs, "SizeConst", module.universe.System_Int32, sizeConst.Value);
|
||||
}
|
||||
if (safeArraySubType != null)
|
||||
{
|
||||
named.Add(new CustomAttributeNamedArgument(typeofMarshalAs.GetField("SafeArraySubType"), new CustomAttributeTypedArgument(typeofVarEnum, safeArraySubType.Value)));
|
||||
AddNamedArgument(named, typeofMarshalAs, "SafeArraySubType", typeofVarEnum, safeArraySubType.Value);
|
||||
}
|
||||
if (safeArrayUserDefinedSubType != null)
|
||||
{
|
||||
named.Add(new CustomAttributeNamedArgument(typeofMarshalAs.GetField("SafeArrayUserDefinedSubType"), new CustomAttributeTypedArgument(typeofType, safeArrayUserDefinedSubType)));
|
||||
AddNamedArgument(named, typeofMarshalAs, "SafeArrayUserDefinedSubType", typeofType, safeArrayUserDefinedSubType);
|
||||
}
|
||||
if (iidParameterIndex != null)
|
||||
{
|
||||
named.Add(new CustomAttributeNamedArgument(typeofMarshalAs.GetField("IidParameterIndex"), new CustomAttributeTypedArgument(module.universe.System_Int32, iidParameterIndex.Value)));
|
||||
AddNamedArgument(named, typeofMarshalAs, "IidParameterIndex", module.universe.System_Int32, iidParameterIndex.Value);
|
||||
}
|
||||
if (marshalType != null)
|
||||
{
|
||||
named.Add(new CustomAttributeNamedArgument(typeofMarshalAs.GetField("MarshalType"), new CustomAttributeTypedArgument(module.universe.System_String, marshalType)));
|
||||
AddNamedArgument(named, typeofMarshalAs, "MarshalType", module.universe.System_String, marshalType);
|
||||
}
|
||||
if (marshalTypeRef != null)
|
||||
{
|
||||
named.Add(new CustomAttributeNamedArgument(typeofMarshalAs.GetField("MarshalTypeRef"), new CustomAttributeTypedArgument(module.universe.System_Type, marshalTypeRef)));
|
||||
AddNamedArgument(named, typeofMarshalAs, "MarshalTypeRef", module.universe.System_Type, marshalTypeRef);
|
||||
}
|
||||
if (marshalCookie != null)
|
||||
{
|
||||
named.Add(new CustomAttributeNamedArgument(typeofMarshalAs.GetField("MarshalCookie"), new CustomAttributeTypedArgument(module.universe.System_String, marshalCookie)));
|
||||
AddNamedArgument(named, typeofMarshalAs, "MarshalCookie", module.universe.System_String, marshalCookie);
|
||||
}
|
||||
ConstructorInfo constructor = typeofMarshalAs.GetConstructor(new Type[] { typeofUnmanagedType });
|
||||
ConstructorInfo constructor = typeofMarshalAs.GetPseudoCustomAttributeConstructor(typeofUnmanagedType);
|
||||
return new CustomAttributeData(module, constructor, new object[] { unmanagedType }, named);
|
||||
}
|
||||
}
|
||||
throw new BadImageFormatException();
|
||||
}
|
||||
|
||||
private static void AddNamedArgument(List<CustomAttributeNamedArgument> list, Type attributeType, string fieldName, Type valueType, object value)
|
||||
{
|
||||
// some fields are not available on the .NET Compact Framework version of MarshalAsAttribute
|
||||
FieldInfo field = attributeType.FindField(fieldName, FieldSignature.Create(valueType, null, null));
|
||||
if (field != null)
|
||||
{
|
||||
list.Add(new CustomAttributeNamedArgument(field, new CustomAttributeTypedArgument(valueType, value)));
|
||||
}
|
||||
}
|
||||
|
||||
internal static void SetMarshalAsAttribute(ModuleBuilder module, int token, CustomAttributeBuilder attribute)
|
||||
{
|
||||
attribute = attribute.DecodeBlob(module.Assembly);
|
||||
|
|
|
@ -128,7 +128,7 @@ namespace IKVM.Reflection.Reader
|
|||
{
|
||||
if (module.FieldLayout.records[i].Field == rid)
|
||||
{
|
||||
ConstructorInfo constructor = module.universe.System_Runtime_InteropServices_FieldOffsetAttribute.GetConstructor(new Type[] { module.universe.System_Int32 });
|
||||
ConstructorInfo constructor = module.universe.System_Runtime_InteropServices_FieldOffsetAttribute.GetPseudoCustomAttributeConstructor(module.universe.System_Int32);
|
||||
list.Add(new CustomAttributeData(module, constructor,
|
||||
new object[] { module.FieldLayout.records[i].Offset },
|
||||
null));
|
||||
|
|
|
@ -266,7 +266,7 @@ namespace IKVM.Reflection.Reader
|
|||
const short CharMapErrorOff = 0x2000;
|
||||
|
||||
Type type = module.universe.System_Runtime_InteropServices_DllImportAttribute;
|
||||
ConstructorInfo constructor = type.GetConstructor(new Type[] { module.universe.System_String });
|
||||
ConstructorInfo constructor = type.GetPseudoCustomAttributeConstructor(module.universe.System_String);
|
||||
List<CustomAttributeNamedArgument> list = new List<CustomAttributeNamedArgument>();
|
||||
int flags = module.ImplMap.records[i].MappingFlags;
|
||||
string entryPoint = module.GetString(module.ImplMap.records[i].ImportName);
|
||||
|
@ -312,10 +312,10 @@ namespace IKVM.Reflection.Reader
|
|||
AddNamedArgument(list, type, "ExactSpelling", flags, NoMangle);
|
||||
AddNamedArgument(list, type, "SetLastError", flags, SupportsLastError);
|
||||
AddNamedArgument(list, type, "PreserveSig", (int)GetMethodImplementationFlags(), (int)MethodImplAttributes.PreserveSig);
|
||||
AddNamedArgument(list, type, "CallingConvention", (int)callingConvention);
|
||||
AddNamedArgument(list, type, "CallingConvention", module.universe.System_Runtime_InteropServices_CallingConvention, (int)callingConvention);
|
||||
if (charSet.HasValue)
|
||||
{
|
||||
AddNamedArgument(list, type, "CharSet", (int)charSet.Value);
|
||||
AddNamedArgument(list, type, "CharSet", module.universe.System_Runtime_InteropServices_CharSet, (int)charSet.Value);
|
||||
}
|
||||
if ((flags & (BestFitOn | BestFitOff)) != 0)
|
||||
{
|
||||
|
@ -349,7 +349,7 @@ namespace IKVM.Reflection.Reader
|
|||
private static void AddNamedArgument(List<CustomAttributeNamedArgument> list, Type attributeType, string fieldName, Type valueType, object value)
|
||||
{
|
||||
// some fields are not available on the .NET Compact Framework version of DllImportAttribute
|
||||
FieldInfo field = attributeType.GetField(fieldName);
|
||||
FieldInfo field = attributeType.FindField(fieldName, FieldSignature.Create(valueType, null, null));
|
||||
if (field != null)
|
||||
{
|
||||
list.Add(new CustomAttributeNamedArgument(field, new CustomAttributeTypedArgument(valueType, value)));
|
||||
|
|
|
@ -1636,6 +1636,16 @@ namespace IKVM.Reflection
|
|||
typeFlags |= TypeFlags.ValueType;
|
||||
return this;
|
||||
}
|
||||
|
||||
internal ConstructorInfo GetPseudoCustomAttributeConstructor(params Type[] parameterTypes)
|
||||
{
|
||||
Universe u = this.Module.universe;
|
||||
MethodSignature methodSig = MethodSignature.MakeFromBuilder(u.System_Void, parameterTypes, null, CallingConventions.Standard | CallingConventions.HasThis, 0);
|
||||
MethodBase mb =
|
||||
FindMethod(".ctor", methodSig) ??
|
||||
u.GetMissingMethodOrThrow(this, ".ctor", methodSig);
|
||||
return (ConstructorInfo)mb;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ElementHolderType : Type
|
||||
|
|
|
@ -125,6 +125,8 @@ namespace IKVM.Reflection
|
|||
private Type typeof_System_Runtime_InteropServices_StructLayoutAttribute;
|
||||
private Type typeof_System_Runtime_InteropServices_OptionalAttribute;
|
||||
private Type typeof_System_Runtime_InteropServices_PreserveSigAttribute;
|
||||
private Type typeof_System_Runtime_InteropServices_CallingConvention;
|
||||
private Type typeof_System_Runtime_InteropServices_CharSet;
|
||||
private Type typeof_System_Runtime_InteropServices_ComImportAttribute;
|
||||
private Type typeof_System_Runtime_CompilerServices_DecimalConstantAttribute;
|
||||
private Type typeof_System_Runtime_CompilerServices_SpecialNameAttribute;
|
||||
|
@ -371,6 +373,16 @@ namespace IKVM.Reflection
|
|||
get { return typeof_System_Runtime_InteropServices_PreserveSigAttribute ?? (typeof_System_Runtime_InteropServices_PreserveSigAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.PreserveSigAttribute))); }
|
||||
}
|
||||
|
||||
internal Type System_Runtime_InteropServices_CallingConvention
|
||||
{
|
||||
get { return typeof_System_Runtime_InteropServices_CallingConvention ?? (typeof_System_Runtime_InteropServices_CallingConvention = ImportMscorlibType(typeof(System.Runtime.InteropServices.CallingConvention))); }
|
||||
}
|
||||
|
||||
internal Type System_Runtime_InteropServices_CharSet
|
||||
{
|
||||
get { return typeof_System_Runtime_InteropServices_CharSet ?? (typeof_System_Runtime_InteropServices_CharSet = ImportMscorlibType(typeof(System.Runtime.InteropServices.CharSet))); }
|
||||
}
|
||||
|
||||
internal Type System_Runtime_InteropServices_ComImportAttribute
|
||||
{
|
||||
get { return typeof_System_Runtime_InteropServices_ComImportAttribute ?? (typeof_System_Runtime_InteropServices_ComImportAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.ComImportAttribute))); }
|
||||
|
|
Загрузка…
Ссылка в новой задаче