提交 932883ad 编写于 作者: F Fadi Hanna

Propagate BestFitMapping/ThrowOnUnmappable from type/assembly

上级 60c362b2
......@@ -454,19 +454,48 @@ public override PInvokeMetadata GetPInvokeMethodMetadata()
return default(PInvokeMetadata);
MetadataReader metadataReader = MetadataReader;
MethodImport import = metadataReader.GetMethodDefinition(_handle).GetImport();
MethodDefinition methodDef = metadataReader.GetMethodDefinition(_handle);
MethodImport import = methodDef.GetImport();
string name = metadataReader.GetString(import.Name);
ModuleReference moduleRef = metadataReader.GetModuleReference(import.Module);
string moduleName = metadataReader.GetString(moduleRef.Name);
MethodImportAttributes importAttributes = import.Attributes;
// If either BestFitMapping or ThrowOnUnmappable wasn't set on the p/invoke,
// look for the value in the owning type or assembly.
if ((importAttributes & MethodImportAttributes.BestFitMappingMask) == 0 ||
(importAttributes & MethodImportAttributes.ThrowOnUnmappableCharMask) == 0)
{
TypeDefinition declaringType = metadataReader.GetTypeDefinition(methodDef.GetDeclaringType());
// Start with owning type
MethodImportAttributes fromCA = GetImportAttributesFromBestFitMappingAttribute(declaringType.GetCustomAttributes());
if ((importAttributes & MethodImportAttributes.BestFitMappingMask) == 0)
importAttributes |= fromCA & MethodImportAttributes.BestFitMappingMask;
if ((importAttributes & MethodImportAttributes.ThrowOnUnmappableCharMask) == 0)
importAttributes |= fromCA & MethodImportAttributes.ThrowOnUnmappableCharMask;
// If we still don't know, check the assembly
if ((importAttributes & MethodImportAttributes.BestFitMappingMask) == 0 ||
(importAttributes & MethodImportAttributes.ThrowOnUnmappableCharMask) == 0)
{
fromCA = GetImportAttributesFromBestFitMappingAttribute(metadataReader.GetAssemblyDefinition().GetCustomAttributes());
if ((importAttributes & MethodImportAttributes.BestFitMappingMask) == 0)
importAttributes |= fromCA & MethodImportAttributes.BestFitMappingMask;
if ((importAttributes & MethodImportAttributes.ThrowOnUnmappableCharMask) == 0)
importAttributes |= fromCA & MethodImportAttributes.ThrowOnUnmappableCharMask;
}
}
// Spot check the enums match
Debug.Assert((int)MethodImportAttributes.CallingConventionStdCall == (int)PInvokeAttributes.CallingConventionStdCall);
Debug.Assert((int)MethodImportAttributes.CharSetAuto == (int)PInvokeAttributes.CharSetAuto);
Debug.Assert((int)MethodImportAttributes.CharSetUnicode == (int)PInvokeAttributes.CharSetUnicode);
Debug.Assert((int)MethodImportAttributes.SetLastError == (int)PInvokeAttributes.SetLastError);
PInvokeAttributes attributes = (PInvokeAttributes)import.Attributes;
PInvokeAttributes attributes = (PInvokeAttributes)importAttributes;
if ((ImplAttributes & MethodImplAttributes.PreserveSig) != 0)
attributes |= PInvokeAttributes.PreserveSig;
......@@ -474,6 +503,47 @@ public override PInvokeMetadata GetPInvokeMethodMetadata()
return new PInvokeMetadata(moduleName, name, attributes);
}
private MethodImportAttributes GetImportAttributesFromBestFitMappingAttribute(CustomAttributeHandleCollection attributeHandles)
{
// Look for the [BestFitMapping(BestFitMapping: x, ThrowOnUnmappableChar = y)] attribute and
// translate that to MethodImportAttributes
MethodImportAttributes result = 0;
MetadataReader reader = MetadataReader;
CustomAttributeHandle attributeHandle = reader.GetCustomAttributeHandle(
attributeHandles, "System.Runtime.InteropServices", "BestFitMappingAttribute");
if (!attributeHandle.IsNil)
{
CustomAttribute attribute = reader.GetCustomAttribute(attributeHandle);
CustomAttributeValue<TypeDesc> decoded = attribute.DecodeValue(
new CustomAttributeTypeProvider(_type.EcmaModule));
if (decoded.FixedArguments.Length != 1 || !(decoded.FixedArguments[0].Value is bool))
ThrowHelper.ThrowBadImageFormatException();
if ((bool)decoded.FixedArguments[0].Value)
result |= MethodImportAttributes.BestFitMappingEnable;
else
result |= MethodImportAttributes.BestFitMappingDisable;
foreach (CustomAttributeNamedArgument<TypeDesc> namedArg in decoded.NamedArguments)
{
if (namedArg.Name == "ThrowOnUnmappableChar")
{
if (!(namedArg.Value is bool))
ThrowHelper.ThrowBadImageFormatException();
if ((bool)namedArg.Value)
result |= MethodImportAttributes.ThrowOnUnmappableCharEnable;
else
result |= MethodImportAttributes.ThrowOnUnmappableCharDisable;
break;
}
}
}
return result;
}
public override ParameterMetadata[] GetParameterMetadata()
{
MetadataReader metadataReader = MetadataReader;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册