Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAtsushi Kanamori <AtsushiKan@users.noreply.github.com>2017-06-06 21:18:56 +0300
committerGitHub <noreply@github.com>2017-06-06 21:18:56 +0300
commitbe9475e8ffb0f123a9c2ebd4b1d662b1aa8a9f8f (patch)
treec1257ae970db3ee418cb85b7fb5e19dbfda6f696 /src/System.Private.Reflection.Execution
parentccb62ad747f5e1e56076bdb8fe8e5a735e9fe61c (diff)
Enum.GetValues() throws on blocked type. (#3801)
Fix https://github.com/dotnet/corert/issues/3797 This prompted a rethink of EnumInfo. This was originally done at a time when we... - Had only one metadata format to support. - Far less support (and desire) for caching Reflection data. Today, - We have three metadata formats to support: * NativeFormat * EcmaFormat * BaloneyFormat (the phony metadata fantasized by blocked types.) - We've restored strong caching for various Reflection data and have the infrastructure for it. Given that, it makes sense now to reimplement EnumInfo on top of the Type abstraction so as not to require all this inside knowledge. We're going to cache the stuff anyway.
Diffstat (limited to 'src/System.Private.Reflection.Execution')
-rw-r--r--src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/EcmaFormatEnumInfoImplementation.cs106
-rw-r--r--src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/EnumInfoImplementation.cs207
-rw-r--r--src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/NativeFormatEnumInfoImplementation.cs122
-rw-r--r--src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ReflectionExecutionDomainCallbacksImplementation.cs26
-rw-r--r--src/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj3
5 files changed, 0 insertions, 464 deletions
diff --git a/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/EcmaFormatEnumInfoImplementation.cs b/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/EcmaFormatEnumInfoImplementation.cs
deleted file mode 100644
index 74e53edb2..000000000
--- a/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/EcmaFormatEnumInfoImplementation.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Reflection;
-using System.Collections.Generic;
-
-using Internal.Runtime.Augments;
-
-using Internal.Reflection.Core;
-using Internal.Reflection.Core.Execution;
-
-using System.Reflection.Metadata;
-
-namespace Internal.Reflection.Execution
-{
- internal sealed class EcmaFormatEnumInfoImplementation : EnumInfoImplementation
- {
- public EcmaFormatEnumInfoImplementation(Type enumType, MetadataReader reader, TypeDefinitionHandle typeDefinitionHandle) : base(enumType)
- {
- _reader = reader;
- _typeDefinition = reader.GetTypeDefinition(typeDefinitionHandle);
- }
-
- protected sealed override KeyValuePair<String, ulong>[] ReadNamesAndValues()
- {
- LowLevelList<KeyValuePair<String, ulong>> namesAndUnboxedValues = new LowLevelList<KeyValuePair<String, ulong>>();
- MetadataReader reader = _reader;
- foreach (FieldDefinitionHandle fieldHandle in _typeDefinition.GetFields())
- {
- FieldDefinition field = reader.GetFieldDefinition(fieldHandle);
- if (0 != (field.Attributes & FieldAttributes.Static))
- {
- String name = reader.GetString(field.Name);
-
- if ((field.Attributes & FieldAttributes.HasDefault) != FieldAttributes.HasDefault)
- throw new BadImageFormatException();
-
- ConstantHandle valueHandle = field.GetDefaultValue();
-
- ulong ulValue = ReadUnboxedEnumValue(reader, valueHandle);
- namesAndUnboxedValues.Add(new KeyValuePair<String, ulong>(name, ulValue));
- }
- }
-
- return namesAndUnboxedValues.ToArray();
- }
-
-
- //
- // This returns the underlying enum values as "ulong" regardless of the actual underlying type. Signed integral types
- // get sign-extended into the 64-bit value, unsigned types get zero-extended.
- //
- public static ulong ReadUnboxedEnumValue(MetadataReader metadataReader, ConstantHandle constantHandle)
- {
- if (constantHandle.IsNil)
- throw new BadImageFormatException();
-
- Constant constantValue = metadataReader.GetConstant(constantHandle);
-
- if (constantValue.Value.IsNil)
- throw new BadImageFormatException();
-
- BlobReader reader = metadataReader.GetBlobReader(constantValue.Value);
-
- switch (constantValue.TypeCode)
- {
- case ConstantTypeCode.Boolean:
- return reader.ReadBoolean() ? 1UL : 0UL;;
-
- case ConstantTypeCode.Char:
- return (ulong)(long)reader.ReadChar();
-
- case ConstantTypeCode.SByte:
- return (ulong)(long)reader.ReadSByte();
-
- case ConstantTypeCode.Int16:
- return (ulong)(long)reader.ReadInt16();
-
- case ConstantTypeCode.Int32:
- return (ulong)(long)reader.ReadInt32();
-
- case ConstantTypeCode.Int64:
- return (ulong)(long)reader.ReadInt64();
-
- case ConstantTypeCode.Byte:
- return (ulong)(long)reader.ReadByte();
-
- case ConstantTypeCode.UInt16:
- return (ulong)(long)reader.ReadUInt16();
-
- case ConstantTypeCode.UInt32:
- return (ulong)(long)reader.ReadUInt32();
-
- case ConstantTypeCode.UInt64:
- return (ulong)(long)reader.ReadUInt64();
- }
-
- throw new BadImageFormatException();
- }
-
- private readonly MetadataReader _reader;
- private readonly TypeDefinition _typeDefinition;
- }
-}
diff --git a/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/EnumInfoImplementation.cs b/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/EnumInfoImplementation.cs
deleted file mode 100644
index e52452507..000000000
--- a/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/EnumInfoImplementation.cs
+++ /dev/null
@@ -1,207 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using global::System;
-using global::System.Reflection;
-using global::System.Collections.Generic;
-
-using global::Internal.Runtime.Augments;
-
-using global::Internal.Reflection.Core;
-using global::Internal.Reflection.Core.Execution;
-
-using global::Internal.Metadata.NativeFormat;
-
-namespace Internal.Reflection.Execution
-{
- internal abstract class EnumInfoImplementation : EnumInfo
- {
- protected EnumInfoImplementation(Type enumType)
- {
- _enumType = enumType;
- }
-
- public sealed override Type UnderlyingType
- {
- get
- {
- return Enum.GetUnderlyingType(_enumType);
- }
- }
-
- public sealed override Array Values
- {
- get
- {
- if (_lazyValues == null)
- {
- RuntimeTypeHandle underlyingTypeHandle = Enum.GetUnderlyingType(_enumType).TypeHandle;
- KeyValuePair<String, ulong>[] namesAndValues = this.NamesAndValues;
- int count = namesAndValues.Length;
- if (underlyingTypeHandle.Equals(typeof(Boolean).TypeHandle))
- {
- Boolean[] a = new Boolean[count];
- for (int i = 0; i < count; i++)
- a[i] = namesAndValues[i].Value != 0 ? true : false;
- _lazyValues = a;
- }
- else if (underlyingTypeHandle.Equals(typeof(Byte).TypeHandle))
- {
- byte[] a = new byte[count];
- for (int i = 0; i < count; i++)
- a[i] = unchecked((byte)(namesAndValues[i].Value));
- _lazyValues = a;
- }
- else if (underlyingTypeHandle.Equals(typeof(SByte).TypeHandle))
- {
- sbyte[] a = new sbyte[count];
- for (int i = 0; i < count; i++)
- a[i] = unchecked((sbyte)(namesAndValues[i].Value));
- _lazyValues = a;
- }
- else if (underlyingTypeHandle.Equals(typeof(UInt16).TypeHandle))
- {
- ushort[] a = new ushort[count];
- for (int i = 0; i < count; i++)
- a[i] = unchecked((ushort)(namesAndValues[i].Value));
- _lazyValues = a;
- }
- else if (underlyingTypeHandle.Equals(typeof(Int16).TypeHandle))
- {
- short[] a = new short[count];
- for (int i = 0; i < count; i++)
- a[i] = unchecked((short)(namesAndValues[i].Value));
- _lazyValues = a;
- }
- else if (underlyingTypeHandle.Equals(typeof(Char).TypeHandle))
- {
- char[] a = new char[count];
- for (int i = 0; i < count; i++)
- a[i] = unchecked((char)(namesAndValues[i].Value));
- _lazyValues = a;
- }
- else if (underlyingTypeHandle.Equals(typeof(UInt32).TypeHandle))
- {
- uint[] a = new uint[count];
- for (int i = 0; i < count; i++)
- a[i] = unchecked((uint)(namesAndValues[i].Value));
- _lazyValues = a;
- }
- else if (underlyingTypeHandle.Equals(typeof(Int32).TypeHandle))
- {
- int[] a = new int[count];
- for (int i = 0; i < count; i++)
- a[i] = unchecked((int)(namesAndValues[i].Value));
- _lazyValues = a;
- }
- else if (underlyingTypeHandle.Equals(typeof(UInt64).TypeHandle))
- {
- ulong[] a = new ulong[count];
- for (int i = 0; i < count; i++)
- a[i] = unchecked((ulong)(namesAndValues[i].Value));
- _lazyValues = a;
- }
- else if (underlyingTypeHandle.Equals(typeof(Int64).TypeHandle))
- {
- long[] a = new long[count];
- for (int i = 0; i < count; i++)
- a[i] = unchecked((long)(namesAndValues[i].Value));
- _lazyValues = a;
- }
- else
- {
- throw new NotSupportedException();
- }
- }
- return _lazyValues;
- }
- }
-
- protected abstract KeyValuePair<String, ulong>[] ReadNamesAndValues();
-
- //
- // This returns the underlying enum values as "ulong" regardless of the actual underlying type. We first do a value-preserving
- // cast to long, then sort it as a ulong.
- //
- public sealed override KeyValuePair<String, ulong>[] NamesAndValues
- {
- get
- {
- if (_lazyNamesAndValues == null)
- {
- KeyValuePair<String, ulong>[] sortedNamesAndUnboxedValues = ReadNamesAndValues();
- Array.Sort<KeyValuePair<String, ulong>>(sortedNamesAndUnboxedValues, new NamesAndValueComparer());
- _lazyNamesAndValues = sortedNamesAndUnboxedValues;
- }
- return _lazyNamesAndValues;
- }
- }
-
- public sealed override bool HasFlagsAttribute
- {
- get
- {
- EnumInfoFlags flags = this.Flags;
- return 0 != (flags & EnumInfoFlags.HasFlagsAttribute);
- }
- }
-
- //
- // Sort comparer for NamesAndValues
- //
- private sealed class NamesAndValueComparer : IComparer<KeyValuePair<String, ulong>>
- {
- public int Compare(KeyValuePair<String, ulong> kv1, KeyValuePair<String, ulong> kv2)
- {
- ulong x = kv1.Value;
- ulong y = kv2.Value;
- if (x < y)
- return -1;
- else if (x > y)
- return 1;
- else
- return 0;
- }
- }
-
- private Type _enumType;
- private volatile Array _lazyValues;
- private volatile KeyValuePair<String, ulong>[] _lazyNamesAndValues;
-
- private EnumInfoFlags Flags
- {
- get
- {
- if (_lazyEnumInfoFlags == 0)
- {
- EnumInfoFlags flags = EnumInfoFlags.Computed;
-
- Type flagsAttributeType = typeof(FlagsAttribute);
- foreach (CustomAttributeData cad in _enumType.CustomAttributes)
- {
- if (cad.AttributeType.Equals(flagsAttributeType))
- {
- flags |= EnumInfoFlags.HasFlagsAttribute;
- break;
- }
- }
-
- _lazyEnumInfoFlags = flags;
- }
- return _lazyEnumInfoFlags;
- }
- }
-
-
-
- [Flags]
- private enum EnumInfoFlags : uint
- {
- Computed = 0x00000001, // always set (to distinguish between computed and not computed)
- HasFlagsAttribute = 0x00000002,
- }
-
- private volatile EnumInfoFlags _lazyEnumInfoFlags;
- }
-}
diff --git a/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/NativeFormatEnumInfoImplementation.cs b/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/NativeFormatEnumInfoImplementation.cs
deleted file mode 100644
index dcea964a6..000000000
--- a/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/NativeFormatEnumInfoImplementation.cs
+++ /dev/null
@@ -1,122 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using global::System;
-using global::System.Reflection;
-using global::System.Collections.Generic;
-
-using global::Internal.Runtime.Augments;
-
-using global::Internal.Reflection.Core;
-using global::Internal.Reflection.Core.Execution;
-
-using global::Internal.Metadata.NativeFormat;
-
-namespace Internal.Reflection.Execution
-{
- internal sealed class NativeFormatEnumInfoImplementation : EnumInfoImplementation
- {
- public NativeFormatEnumInfoImplementation(Type enumType, MetadataReader reader, TypeDefinitionHandle typeDefinitionHandle) : base(enumType)
- {
- _reader = reader;
- _typeDefinition = typeDefinitionHandle.GetTypeDefinition(reader);
- }
-
- protected sealed override KeyValuePair<String, ulong>[] ReadNamesAndValues()
- {
- LowLevelList<KeyValuePair<String, ulong>> namesAndUnboxedValues = new LowLevelList<KeyValuePair<String, ulong>>();
- MetadataReader reader = _reader;
- foreach (FieldHandle fieldHandle in _typeDefinition.Fields)
- {
- Field field = fieldHandle.GetField(reader);
- if (0 != (field.Flags & FieldAttributes.Static))
- {
- String name = field.Name.GetString(reader);
- Handle valueHandle = field.DefaultValue;
- ulong lValue = ReadUnboxedEnumValue(reader, valueHandle);
- namesAndUnboxedValues.Add(new KeyValuePair<String, ulong>(name, lValue));
- }
- }
-
- return namesAndUnboxedValues.ToArray();
- }
-
- //
- // This returns the underlying enum values as "ulong" regardless of the actual underlying type. Signed integral types
- // get sign-extended into the 64-bit value, unsigned types get zero-extended.
- //
- private static ulong ReadUnboxedEnumValue(MetadataReader reader, Handle valueHandle)
- {
- HandleType handleType = valueHandle.HandleType;
- switch (handleType)
- {
- case HandleType.ConstantBooleanValue:
- {
- bool v = valueHandle.ToConstantBooleanValueHandle(reader).GetConstantBooleanValue(reader).Value;
- return v ? 1UL : 0UL;
- }
-
- case HandleType.ConstantCharValue:
- {
- char v = valueHandle.ToConstantCharValueHandle(reader).GetConstantCharValue(reader).Value;
- return (ulong)(long)v;
- }
-
- case HandleType.ConstantByteValue:
- {
- byte v = valueHandle.ToConstantByteValueHandle(reader).GetConstantByteValue(reader).Value;
- return (ulong)(long)v;
- }
-
- case HandleType.ConstantSByteValue:
- {
- sbyte v = valueHandle.ToConstantSByteValueHandle(reader).GetConstantSByteValue(reader).Value;
- return (ulong)(long)v;
- }
-
- case HandleType.ConstantUInt16Value:
- {
- UInt16 v = valueHandle.ToConstantUInt16ValueHandle(reader).GetConstantUInt16Value(reader).Value;
- return (ulong)(long)v;
- }
-
- case HandleType.ConstantInt16Value:
- {
- Int16 v = valueHandle.ToConstantInt16ValueHandle(reader).GetConstantInt16Value(reader).Value;
- return (ulong)(long)v;
- }
-
- case HandleType.ConstantUInt32Value:
- {
- UInt32 v = valueHandle.ToConstantUInt32ValueHandle(reader).GetConstantUInt32Value(reader).Value;
- return (ulong)(long)v;
- }
-
- case HandleType.ConstantInt32Value:
- {
- Int32 v = valueHandle.ToConstantInt32ValueHandle(reader).GetConstantInt32Value(reader).Value;
- return (ulong)(long)v;
- }
-
- case HandleType.ConstantUInt64Value:
- {
- UInt64 v = valueHandle.ToConstantUInt64ValueHandle(reader).GetConstantUInt64Value(reader).Value;
- return (ulong)(long)v;
- }
-
- case HandleType.ConstantInt64Value:
- {
- Int64 v = valueHandle.ToConstantInt64ValueHandle(reader).GetConstantInt64Value(reader).Value;
- return (ulong)(long)v;
- }
-
- default:
- throw new BadImageFormatException();
- }
- }
-
- private readonly MetadataReader _reader;
- private readonly TypeDefinition _typeDefinition;
- }
-}
diff --git a/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ReflectionExecutionDomainCallbacksImplementation.cs b/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ReflectionExecutionDomainCallbacksImplementation.cs
index cecab67cf..561fc6939 100644
--- a/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ReflectionExecutionDomainCallbacksImplementation.cs
+++ b/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ReflectionExecutionDomainCallbacksImplementation.cs
@@ -96,32 +96,6 @@ namespace Internal.Reflection.Execution
return _executionDomain.CreateMissingMetadataException(pertainant);
}
- public sealed override EnumInfo GetEnumInfoIfAvailable(Type enumType)
- {
- // Handle the weird case of an enum type nested under a generic type that makes the
- // enum itself generic.
- if (enumType.IsConstructedGenericType)
- {
- enumType = enumType.GetGenericTypeDefinition();
- }
-
- QTypeDefinition qTypeDefinition;
- if (!ReflectionExecution.ExecutionEnvironment.TryGetMetadataForNamedType(enumType.TypeHandle, out qTypeDefinition))
- return null;
-
- if (qTypeDefinition.IsNativeFormatMetadataBased)
- {
- return new NativeFormatEnumInfoImplementation(enumType, qTypeDefinition.NativeFormatReader, qTypeDefinition.NativeFormatHandle);
- }
-#if ECMA_METADATA_SUPPORT
- if (qTypeDefinition.IsEcmaFormatMetadataBased)
- {
- return new EcmaFormatEnumInfoImplementation(enumType, qTypeDefinition.EcmaFormatReader, qTypeDefinition.EcmaFormatHandle);
- }
-#endif
- return null;
- }
-
// This is called from the ToString() helper of a RuntimeType that does not have full metadata.
// This helper makes a "best effort" to give the caller something better than "EETypePtr nnnnnnnnn".
public sealed override String GetBetterDiagnosticInfoIfAvailable(RuntimeTypeHandle runtimeTypeHandle)
diff --git a/src/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj b/src/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj
index a8d369995..df12d0431 100644
--- a/src/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj
+++ b/src/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj
@@ -53,7 +53,6 @@
</PropertyGroup>
<ItemGroup Condition="'$(EcmaMetadataSupport)' == 'true'">
<Compile Include="Internal\Reflection\Execution\PayForPlayExperience\DiagnosticMappingTables.Ecma.cs" />
- <Compile Include="Internal\Reflection\Execution\EcmaFormatEnumInfoImplementation.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="$(NativeFormatCommonPath)\NativeFormat.cs" />
@@ -76,8 +75,6 @@
<Compile Include="Internal\Reflection\Execution\ExecutionEnvironmentImplementation.ManifestResources.cs" />
<Compile Include="Internal\Reflection\Execution\ReflectionExecutionDomainCallbacksImplementation.cs" />
<Compile Include="Internal\Reflection\Execution\MetadataReaderExtensions.cs" />
- <Compile Include="Internal\Reflection\Execution\EnumInfoImplementation.cs" />
- <Compile Include="Internal\Reflection\Execution\NativeFormatEnumInfoImplementation.cs" />
<Compile Include="Internal\Reflection\Execution\DefaultValueParser.cs" />
<Compile Include="Internal\Reflection\Execution\MethodInvokeInfo.cs" />
<Compile Include="Internal\Reflection\Execution\RuntimeHandlesExtensions.cs" />