diff options
author | Jan Kotas <jkotas@microsoft.com> | 2016-09-18 00:09:24 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-09-18 00:09:24 +0300 |
commit | 36a78d03720966ccd37c9ea464b9f7f362506be8 (patch) | |
tree | 3dbba1855f5b50652f603de009a0dd7ad63f0055 | |
parent | c6a2b271f5cc6d5b4c271e1dd9ecb364b5a2743c (diff) | |
parent | 3128685e6209f77fef2f0aac9ef8db33038c8ecf (diff) |
Merge pull request #1863 from dotnet/nmirror
Merge nmirror to master
28 files changed, 233 insertions, 539 deletions
diff --git a/src/Common/src/TypeSystem/IL/Stubs/UnsafeIntrinsics.cs b/src/Common/src/TypeSystem/IL/Stubs/UnsafeIntrinsics.cs index 8663005fb..3eb54856c 100644 --- a/src/Common/src/TypeSystem/IL/Stubs/UnsafeIntrinsics.cs +++ b/src/Common/src/TypeSystem/IL/Stubs/UnsafeIntrinsics.cs @@ -21,6 +21,8 @@ namespace Internal.IL.Stubs switch (method.Name) { + case "AsPointer": + return new ILStubMethodIL(method, new byte[] { (byte)ILOpcode.ldarg_0, (byte)ILOpcode.conv_u, (byte)ILOpcode.ret }, Array.Empty<LocalVariableDefinition>(), null); case "SizeOf": return EmitSizeOf(method); case "As": diff --git a/src/System.Private.CoreLib/src/MembersMustExist.AnalyzerData b/src/System.Private.CoreLib/src/MembersMustExist.AnalyzerData index 2309d4820..e41526452 100644 --- a/src/System.Private.CoreLib/src/MembersMustExist.AnalyzerData +++ b/src/System.Private.CoreLib/src/MembersMustExist.AnalyzerData @@ -61,22 +61,6 @@ public void System.Array.CopyTo(System.Array array, int index) # System.Runtime.InteropServices public static System.Runtime.InteropServices.GCHandle System.Runtime.InteropServices.GCHandle.Alloc(object value, System.Runtime.InteropServices.GCHandleType type) -# ByReference<T> -internal static extern System.Runtime.CompilerServices.ByReference<T> System.Runtime.CompilerServices.ByReference<T>.AddRaw(System.Runtime.CompilerServices.ByReference<T> pointer, int rawOffset) -public static extern System.Runtime.CompilerServices.ByReference<T1> System.Runtime.CompilerServices.ByReference<T>.Cast<T1>(System.Runtime.CompilerServices.ByReference<T> pointer) -public static extern System.Runtime.CompilerServices.ByReference<T> System.Runtime.CompilerServices.ByReference<T>.FromRef(ref T pointer) -public static extern T System.Runtime.CompilerServices.ByReference<T>.Load(System.Runtime.CompilerServices.ByReference<T> pointer) -private static extern bool System.Runtime.CompilerServices.ByReference<T>.PointerEquals(System.Runtime.CompilerServices.ByReference<T> value1, System.Runtime.CompilerServices.ByReference<T> value2) -private static extern int System.Runtime.CompilerServices.ByReference<T>.SizeOfTUnsigned() -internal static extern void System.Runtime.CompilerServices.ByReference<T>.Store(System.Runtime.CompilerServices.ByReference<T> pointer, T value) -private static extern System.Runtime.CompilerServices.ByReference<T> System.Runtime.CompilerServices.ByReference<T>.SubRaw(System.Runtime.CompilerServices.ByReference<T> pointer, int rawOffset) -public static extern System.UIntPtr System.Runtime.CompilerServices.ByReference<T>.ToPointer(System.Runtime.CompilerServices.ByReference<T> pointer) -private static extern int System.Runtime.CompilerServices.ByReference<T>.UncheckedMul(int a, int b) -public static System.Runtime.CompilerServices.ByReference<T> System.Runtime.CompilerServices.ByReference<T>.Add(System.Runtime.CompilerServices.ByReference<T> pointer, int offset) -public static T System.Runtime.CompilerServices.ByReference<T>.LoadAtIndex(System.Runtime.CompilerServices.ByReference<T> pointer, int index) -internal static int System.Runtime.CompilerServices.ByReference<T>.SizeOfT() -internal static void System.Runtime.CompilerServices.ByReference<T>.StoreAtIndex(System.Runtime.CompilerServices.ByReference<T> pointer, int index, T value) - # System.SR internal static string System.SR.GetResourceString(string resourceKey) internal static string System.SR.GetResourceString(string resourceKey, string defaultString) diff --git a/src/System.Private.CoreLib/src/System/Globalization/CompareInfo.Windows.cs b/src/System.Private.CoreLib/src/System/Globalization/CompareInfo.Windows.cs index 2a25decc9..c67167500 100644 --- a/src/System.Private.CoreLib/src/System/Globalization/CompareInfo.Windows.cs +++ b/src/System.Private.CoreLib/src/System/Globalization/CompareInfo.Windows.cs @@ -271,14 +271,10 @@ namespace System.Globalization int sourceStartIndex = findLastIndex ? startIndex - sourceCount + 1 : startIndex; -#if !TEST_CODEGEN_OPTIMIZATION fixed (char* pSource = source, spTarget = target) { char* spSubSource = pSource + sourceStartIndex; -#else - String.StringPointer spSubSource = source.GetStringPointer(sourceStartIndex); - String.StringPointer spTarget = target.GetStringPointer(); -#endif + if (findLastIndex) { int startPattern = (sourceCount - 1) - targetCount + 1; @@ -338,11 +334,9 @@ namespace System.Globalization retValue += startIndex; } } -#if !TEST_CODEGEN_OPTIMIZATION } return retValue; -#endif // TEST_CODEGEN_OPTIMIZATION } private const int COMPARE_OPTIONS_ORDINAL = 0x40000000; // Ordinal diff --git a/src/System.Private.CoreLib/src/System/Globalization/FormatProvider.NumberBuffer.cs b/src/System.Private.CoreLib/src/System/Globalization/FormatProvider.NumberBuffer.cs index 8ef64cee9..b36a6565b 100644 --- a/src/System.Private.CoreLib/src/System/Globalization/FormatProvider.NumberBuffer.cs +++ b/src/System.Private.CoreLib/src/System/Globalization/FormatProvider.NumberBuffer.cs @@ -27,62 +27,18 @@ namespace System.Globalization public Int32 scale; public Boolean sign; - // First character of an inline array of NumberMaxDigits characters. - private char _char01; - private char _char02; - private char _char03; - private char _char04; - private char _char05; - private char _char06; - private char _char07; - private char _char08; - private char _char09; - private char _char10; - private char _char11; - private char _char12; - private char _char13; - private char _char14; - private char _char15; - private char _char16; - private char _char17; - private char _char18; - private char _char19; - private char _char20; - private char _char21; - private char _char22; - private char _char23; - private char _char24; - private char _char25; - private char _char26; - private char _char27; - private char _char28; - private char _char29; - private char _char30; - private char _char31; - private char _char32; + // Inline array of NumberMaxDigits characters. + private fixed char buffer[32]; public char* digits { get { // This is only safe if the caller allocated the NumberBuffer on the stack or pinned it. - -#if CORERT - unsafe - { - fixed (char* p = &_char01) - return p; - } -#else - // using the ManagedPointer instead of fixed allows the compiler to inline this property - // and thus make it more efficient. - System.Runtime.CompilerServices.ByReference<char> mp = System.Runtime.CompilerServices.ByReference<char>.FromRef(ref _char01); - return (char*)System.Runtime.CompilerServices.ByReference<char>.ToPointer(mp); -#endif + return ((NumberBuffer*)Unsafe.AsPointer(ref this))->buffer; } } } } } } - diff --git a/src/System.Private.CoreLib/src/System/MDArray.cs b/src/System.Private.CoreLib/src/System/MDArray.cs index 844119410..4e6570cb4 100644 --- a/src/System.Private.CoreLib/src/System/MDArray.cs +++ b/src/System.Private.CoreLib/src/System/MDArray.cs @@ -39,20 +39,23 @@ namespace System private IntPtr _count; private int _upperBound1; private int _upperBound2; + private int _lowerBound1; + private int _lowerBound2; + private T _data; public static T[,] Ctor(int length1, int length2) { if ((length1 < 0) || (length2 < 0)) throw new OverflowException(); - MDArrayRank2<T> newArray = Unsafe.As<MDArrayRank2<T>>(RuntimeImports.RhNewArray(typeof(T[,]).TypeHandle.ToEETypePtr(), checked(length1 * length2))); + MDArrayRank2<T> newArray = Unsafe.As<MDArrayRank2<T>>(RuntimeImports.RhNewArray(typeof(T[,]).TypeHandle.ToEETypePtr(), checked(length1 * length2))); newArray._upperBound1 = length1; newArray._upperBound2 = length2; return Unsafe.As<T[,]>(newArray); } [MethodImpl(MethodImplOptions.NoInlining)] - private static ByReference<T> InternalAddress(T[,] array, int index1, int index2) + private static ref T InternalAddress(T[,] array, int index1, int index2) { MDArrayRank2<T> mdArrayObj = Unsafe.As<MDArrayRank2<T>>(array); if ((index1 < 0) || (index1 >= mdArrayObj._upperBound1)) @@ -61,36 +64,33 @@ namespace System throw new IndexOutOfRangeException(); int index = (index1 * mdArrayObj._upperBound2) + index2; - - int offset = ByReference<T>.SizeOfT() * index + 2 * 8; - ByReference<int> _upperBound1Ref = ByReference<int>.FromRef(ref mdArrayObj._upperBound1); - return ByReference<int>.Cast<T>(ByReference<int>.AddRaw(_upperBound1Ref, offset)); + return ref Unsafe.Add(ref mdArrayObj._data, index); } - public static ByReference<T> Address(T[,] array, int index1, int index2) + public static ref T Address(T[,] array, int index1, int index2) { - ByReference<T> returnValue = InternalAddress(array, index1, index2); - if (!typeof(T).TypeHandle.ToEETypePtr().IsValueType) + ref T returnValue = ref InternalAddress(array, index1, index2); + if (!EETypePtr.EETypePtrOf<T>().IsValueType) { - if (!typeof(T).TypeHandle.Equals(new RuntimeTypeHandle(array.EETypePtr.ArrayElementType))) + if (!EETypePtr.EETypePtrOf<T>().FastEquals(array.EETypePtr.ArrayElementType)) throw new ArrayTypeMismatchException(); } - return returnValue; + return ref returnValue; } public static T Get(T[,] array, int index1, int index2) { - return ByReference<T>.Load(InternalAddress(array, index1, index2)); + return InternalAddress(array, index1, index2); } public static void Set(T[,] array, int index1, int index2, T value) { - if (!typeof(T).TypeHandle.ToEETypePtr().IsValueType) + if (!EETypePtr.EETypePtrOf<T>().IsValueType) { RuntimeImports.RhCheckArrayStore(array, value); } - ByReference<T>.Store(InternalAddress(array, index1, index2), value); + InternalAddress(array, index1, index2) = value; } } @@ -101,13 +101,17 @@ namespace System private int _upperBound1; private int _upperBound2; private int _upperBound3; + private int _lowerBound1; + private int _lowerBound2; + private int _lowerBound3; + private T _data; public static T[,,] Ctor(int length1, int length2, int length3) { if ((length1 < 0) || (length2 < 0) || (length3 < 0)) throw new OverflowException(); - MDArrayRank3<T> newArray = Unsafe.As<MDArrayRank3<T>>(RuntimeImports.RhNewArray(typeof(T[,,]).TypeHandle.ToEETypePtr(), checked(length1 * length2 * length3))); + MDArrayRank3<T> newArray = Unsafe.As<MDArrayRank3<T>>(RuntimeImports.RhNewArray(typeof(T[,,]).TypeHandle.ToEETypePtr(), checked(length1 * length2 * length3))); newArray._upperBound1 = length1; newArray._upperBound2 = length2; newArray._upperBound3 = length3; @@ -115,7 +119,7 @@ namespace System } [MethodImpl(MethodImplOptions.NoInlining)] - private static ByReference<T> InternalAddress(T[,,] array, int index1, int index2, int index3) + private static ref T InternalAddress(T[,,] array, int index1, int index2, int index3) { MDArrayRank3<T> mdArrayObj = Unsafe.As<MDArrayRank3<T>>(array); if ((index1 < 0) || (index1 >= mdArrayObj._upperBound1)) @@ -126,36 +130,33 @@ namespace System throw new IndexOutOfRangeException(); int index = (((index1 * mdArrayObj._upperBound2) + index2) * mdArrayObj._upperBound3) + index3; - - int offset = ByReference<T>.SizeOfT() * index + 3 * 8; - ByReference<int> _upperBound1Ref = ByReference<int>.FromRef(ref mdArrayObj._upperBound1); - return ByReference<int>.Cast<T>(ByReference<int>.AddRaw(_upperBound1Ref, offset)); + return ref Unsafe.Add(ref mdArrayObj._data, index); } - public static ByReference<T> Address(T[,,] array, int index1, int index2, int index3) + public static ref T Address(T[,,] array, int index1, int index2, int index3) { - ByReference<T> returnValue = InternalAddress(array, index1, index2, index3); - if (!typeof(T).TypeHandle.ToEETypePtr().IsValueType) + ref T returnValue = ref InternalAddress(array, index1, index2, index3); + if (!EETypePtr.EETypePtrOf<T>().IsValueType) { - if (!typeof(T).TypeHandle.Equals(new RuntimeTypeHandle(array.EETypePtr.ArrayElementType))) + if (!EETypePtr.EETypePtrOf<T>().FastEquals(array.EETypePtr.ArrayElementType)) throw new ArrayTypeMismatchException(); } - return returnValue; + return ref returnValue; } public static T Get(T[,,] array, int index1, int index2, int index3) { - return ByReference<T>.Load(InternalAddress(array, index1, index2, index3)); + return InternalAddress(array, index1, index2, index3); } public static void Set(T[,,] array, int index1, int index2, int index3, T value) { - if (!typeof(T).TypeHandle.ToEETypePtr().IsValueType) + if (!EETypePtr.EETypePtrOf<T>().IsValueType) { RuntimeImports.RhCheckArrayStore(array, value); } - ByReference<T>.Store(InternalAddress(array, index1, index2, index3), value); + InternalAddress(array, index1, index2, index3) = value; } } @@ -167,13 +168,18 @@ namespace System private int _upperBound2; private int _upperBound3; private int _upperBound4; + private int _lowerBound1; + private int _lowerBound2; + private int _lowerBound3; + private int _lowerBound4; + private T _data; public static T[,,,] Ctor(int length1, int length2, int length3, int length4) { if ((length1 < 0) || (length2 < 0) || (length3 < 0) || (length4 < 0)) throw new OverflowException(); - MDArrayRank4<T> newArray = Unsafe.As<MDArrayRank4<T>>(RuntimeImports.RhNewArray(typeof(T[,,,]).TypeHandle.ToEETypePtr(), checked(length1 * length2 * length3 * length4))); + MDArrayRank4<T> newArray = Unsafe.As<MDArrayRank4<T>>(RuntimeImports.RhNewArray(typeof(T[,,,]).TypeHandle.ToEETypePtr(), checked(length1 * length2 * length3 * length4))); newArray._upperBound1 = length1; newArray._upperBound2 = length2; newArray._upperBound3 = length3; @@ -182,7 +188,7 @@ namespace System } [MethodImpl(MethodImplOptions.NoInlining)] - private static ByReference<T> InternalAddress(T[,,,] array, int index1, int index2, int index3, int index4) + private static ref T InternalAddress(T[,,,] array, int index1, int index2, int index3, int index4) { MDArrayRank4<T> mdArrayObj = Unsafe.As<MDArrayRank4<T>>(array); if ((index1 < 0) || (index1 >= mdArrayObj._upperBound1)) @@ -195,37 +201,33 @@ namespace System throw new IndexOutOfRangeException(); int index = (((((index1 * mdArrayObj._upperBound2) + index2) * mdArrayObj._upperBound3) + index3) * mdArrayObj._upperBound4) + index4; - - - int offset = ByReference<T>.SizeOfT() * index + 4 * 8; - ByReference<int> _upperBound1Ref = ByReference<int>.FromRef(ref mdArrayObj._upperBound1); - return ByReference<int>.Cast<T>(ByReference<int>.AddRaw(_upperBound1Ref, offset)); + return ref Unsafe.Add(ref mdArrayObj._data, index); } - public static ByReference<T> Address(T[,,,] array, int index1, int index2, int index3, int index4) + public static ref T Address(T[,,,] array, int index1, int index2, int index3, int index4) { - ByReference<T> returnValue = InternalAddress(array, index1, index2, index3, index4); - if (!typeof(T).TypeHandle.ToEETypePtr().IsValueType) + ref T returnValue = ref InternalAddress(array, index1, index2, index3, index4); + if (!EETypePtr.EETypePtrOf<T>().IsValueType) { - if (!typeof(T).TypeHandle.Equals(new RuntimeTypeHandle(array.EETypePtr.ArrayElementType))) + if (!EETypePtr.EETypePtrOf<T>().FastEquals(array.EETypePtr.ArrayElementType)) throw new ArrayTypeMismatchException(); } - return returnValue; + return ref returnValue; } public static T Get(T[,,,] array, int index1, int index2, int index3, int index4) { - return ByReference<T>.Load(InternalAddress(array, index1, index2, index3, index4)); + return InternalAddress(array, index1, index2, index3, index4); } public static void Set(T[,,,] array, int index1, int index2, int index3, int index4, T value) { - if (!typeof(T).TypeHandle.ToEETypePtr().IsValueType) + if (!EETypePtr.EETypePtrOf<T>().IsValueType) { RuntimeImports.RhCheckArrayStore(array, (object)value); } - ByReference<T>.Store(InternalAddress(array, index1, index2, index3, index4), value); + InternalAddress(array, index1, index2, index3, index4) = value; } } } diff --git a/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/InternalCompilerAttributes.cs b/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/InternalCompilerAttributes.cs index 036568e6a..298b4e466 100644 --- a/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/InternalCompilerAttributes.cs +++ b/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/InternalCompilerAttributes.cs @@ -22,8 +22,8 @@ namespace System.Runtime.CompilerServices [AttributeUsage(AttributeTargets.Struct)] public sealed class StackOnlyAttribute : Attribute { } -#if !CORERT - // This is a dummy class to be replaced by the compiler with a in T +#if false // Unused right now. It is likely going to be useful for Span<T> implementation. + // This is a dummy class to be replaced by the compiler with a ref T // It has to be a dummy class to avoid complicated type substitution // and other complications in the compiler. public sealed class ByReference<T> @@ -32,67 +32,10 @@ namespace System.Runtime.CompilerServices // Managed pointer creation // [Intrinsic] - public static extern ByReference<T> FromRef(ref T pointer); - - [Intrinsic] - [CLSCompliant(false)] - public static extern UIntPtr ToPointer(ByReference<T> pointer); - - [Intrinsic] - public static extern ByReference<T1> Cast<T1>(ByReference<T> pointer); - - // - // Value access - // - [Intrinsic] - public static extern T Load(ByReference<T> pointer); - - [Intrinsic] - internal static extern void Store(ByReference<T> pointer, T value); - - public static T LoadAtIndex(ByReference<T> pointer, int index) - { - ByReference<T> temp = Add(pointer, index); - return Load(temp); - } - - internal static void StoreAtIndex(ByReference<T> pointer, int index, T value) - { - ByReference<T> temp = Add(pointer, index); - Store(temp, value); - } - - // - // Pointer arithmetic - // - [Intrinsic] - internal static extern ByReference<T> AddRaw(ByReference<T> pointer, int rawOffset); - - [Intrinsic] - private static extern ByReference<T> SubRaw(ByReference<T> pointer, int rawOffset); - - [Intrinsic] - private static extern int UncheckedMul(int a, int b); - - [Intrinsic] - private static extern int SizeOfTUnsigned(); - - internal static int SizeOfT() - { - unchecked - { - // The IL sizeof(T) is unsigned but we need signed integer for all our uses. - return (int)SizeOfTUnsigned(); - } - } - - public static ByReference<T> Add(ByReference<T> pointer, int offset) - { - return AddRaw(pointer, UncheckedMul(offset, SizeOfT())); - } + public static extern ByReference<T> FromRef(ref T source); [Intrinsic] - private static extern bool PointerEquals(ByReference<T> value1, ByReference<T> value2); + public static extern ref T ToRef(ByReference<T> source); } #endif } diff --git a/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/Unsafe.cs b/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/Unsafe.cs index cebb68705..b0653829c 100644 --- a/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/Unsafe.cs +++ b/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/Unsafe.cs @@ -22,6 +22,26 @@ namespace System.Runtime.CompilerServices /// </summary> public static class Unsafe { + /// <summary> + /// Returns a pointer to the given by-ref parameter. + /// </summary> + [CLSCompliant(false)] + [Intrinsic] + [NonVersionable] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe void* AsPointer<T>(ref T source) + { + // This method is implemented by the toolchain + throw new PlatformNotSupportedException(); + + // ldarg.0 + // conv.u + // ret + } + + /// <summary> + /// Returns the size of an object of the given type parameter. + /// </summary> [Intrinsic] [NonVersionable] [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/System.Private.CoreLib/src/System/String.cs b/src/System.Private.CoreLib/src/System/String.cs index 990e2fe82..b87e82cdb 100644 --- a/src/System.Private.CoreLib/src/System/String.cs +++ b/src/System.Private.CoreLib/src/System/String.cs @@ -304,15 +304,13 @@ namespace System { if ((uint)index >= _stringLength) throw new IndexOutOfRangeException(); - fixed (char* s = &_firstChar) - return s[index]; + return Unsafe.Add(ref _firstChar, index); } #else [BoundsChecking] get { - System.Runtime.CompilerServices.ByReference<char> mgdPtr = System.Runtime.CompilerServices.ByReference<char>.FromRef(ref _firstChar); - return System.Runtime.CompilerServices.ByReference<char>.LoadAtIndex(mgdPtr, index); + return Unsafe.Add(ref _firstChar, index); } #endif } @@ -590,42 +588,6 @@ namespace System return count; } -#if !CORERT - // This method give you access raw access to a unpinned (i.e. don't hand out via interop) - // string data to do efficent string indexing and substring operations. - internal StringPointer GetStringPointer(int startIndex = 0) - { - return new StringPointer(this, startIndex); - } - - [System.Runtime.CompilerServices.StackOnly] - internal struct StringPointer - { - private string _theString; - private int _index; - - public StringPointer(string s, int startIndex = 0) - { - _theString = s; - _index = startIndex; - } - - public char this[int offset] - { - get - { - System.Runtime.CompilerServices.ByReference<char> mgdPtr = System.Runtime.CompilerServices.ByReference<char>.FromRef(ref _theString._firstChar); - return System.Runtime.CompilerServices.ByReference<char>.LoadAtIndex(mgdPtr, offset + _index); - } - set - { - System.Runtime.CompilerServices.ByReference<char> mgdPtr = System.Runtime.CompilerServices.ByReference<char>.FromRef(ref _theString._firstChar); - System.Runtime.CompilerServices.ByReference<char>.StoreAtIndex(mgdPtr, offset + _index, value); - } - } - } -#endif - // // IConvertible implementation // diff --git a/src/System.Private.Reflection.Core/src/Internal/Reflection/Core/Execution/ExecutionDomain.cs b/src/System.Private.Reflection.Core/src/Internal/Reflection/Core/Execution/ExecutionDomain.cs index a1c58ccb6..bd3d6d299 100644 --- a/src/System.Private.Reflection.Core/src/Internal/Reflection/Core/Execution/ExecutionDomain.cs +++ b/src/System.Private.Reflection.Core/src/Internal/Reflection/Core/Execution/ExecutionDomain.cs @@ -124,7 +124,9 @@ namespace Internal.Reflection.Core.Execution } else { - RuntimeNamedMethodInfo runtimeNamedMethodInfo = RuntimeNamedMethodInfo.GetRuntimeNamedMethodInfo(methodHandle, definingTypeInfo, contextTypeInfo); + // RuntimeMethodHandles always yield methods whose ReflectedType is the DeclaringType. + RuntimeTypeInfo reflectedType = contextTypeInfo; + RuntimeNamedMethodInfo runtimeNamedMethodInfo = RuntimeNamedMethodInfo.GetRuntimeNamedMethodInfo(methodHandle, definingTypeInfo, contextTypeInfo, reflectedType); if (!runtimeNamedMethodInfo.IsGenericMethod) { return runtimeNamedMethodInfo; diff --git a/src/System.Private.Reflection.Core/src/System.Private.Reflection.Core.csproj b/src/System.Private.Reflection.Core/src/System.Private.Reflection.Core.csproj index 1be0bf056..29e0976ad 100644 --- a/src/System.Private.Reflection.Core/src/System.Private.Reflection.Core.csproj +++ b/src/System.Private.Reflection.Core/src/System.Private.Reflection.Core.csproj @@ -46,7 +46,6 @@ <Compile Include="System\Reflection\Runtime\Assemblies\RuntimeAssemblyName.cs" /> <Compile Include="System\Reflection\Runtime\BindingFlagSupport\DefaultBinder.cs" /> <Compile Include="System\Reflection\Runtime\BindingFlagSupport\DefaultBinder.LimitedBinder.cs" /> - <Compile Include="System\Reflection\Runtime\BindingFlagSupport\InheritedPropertyInfo.cs" /> <Compile Include="System\Reflection\Runtime\BindingFlagSupport\MemberEnumerator.cs" /> <Compile Include="System\Reflection\Runtime\BindingFlagSupport\MemberPolicies.cs" /> <Compile Include="System\Reflection\Runtime\BindingFlagSupport\MemberTypeIndex.cs" /> diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/InheritedPropertyInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/InheritedPropertyInfo.cs deleted file mode 100644 index c0022ec46..000000000 --- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/InheritedPropertyInfo.cs +++ /dev/null @@ -1,260 +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.Diagnostics; -using System.Globalization; -using System.Collections.Generic; - -namespace System.Reflection.Runtime.BindingFlagSupport -{ - // - // This class exists for desktop compatibility. If one uses an api such as Type.GetProperty(string) to retrieve a member - // from a base class, the desktop returns a special MemberInfo object that is blocked from seeing or invoking private - // set or get methods on that property. That is, the type used to find the member is part of that member's object identity. - // - internal sealed class InheritedPropertyInfo : PropertyInfo - { - private readonly PropertyInfo _underlyingPropertyInfo; - private readonly Type _reflectedType; - - internal InheritedPropertyInfo(PropertyInfo underlyingPropertyInfo, Type reflectedType) - { - // If the reflectedType is the declaring type, the caller should have used the original PropertyInfo. - // This assert saves us from having to check this throughout. - Debug.Assert(!(reflectedType.Equals(underlyingPropertyInfo.DeclaringType)), "reflectedType must be a proper base type of (and not equal to) underlyingPropertyInfo.DeclaringType."); - - _underlyingPropertyInfo = underlyingPropertyInfo; - _reflectedType = reflectedType; - return; - } - - public sealed override PropertyAttributes Attributes - { - get { return _underlyingPropertyInfo.Attributes; } - } - - public sealed override bool CanRead - { - get { return GetMethod != null; } - } - - public sealed override bool CanWrite - { - get { return SetMethod != null; } - } - - public sealed override ParameterInfo[] GetIndexParameters() - { - return _underlyingPropertyInfo.GetIndexParameters(); - } - - public sealed override Type PropertyType - { - get { return _underlyingPropertyInfo.PropertyType; } - } - - public sealed override Type DeclaringType - { - get { return _underlyingPropertyInfo.DeclaringType; } - } - - public sealed override String Name - { - get { return _underlyingPropertyInfo.Name; } - } - - public sealed override IEnumerable<CustomAttributeData> CustomAttributes - { - get { return _underlyingPropertyInfo.CustomAttributes; } - } - - public sealed override bool Equals(Object obj) - { - InheritedPropertyInfo other = obj as InheritedPropertyInfo; - if (other == null) - { - return false; - } - - if (!(_underlyingPropertyInfo.Equals(other._underlyingPropertyInfo))) - { - return false; - } - - if (!(_reflectedType.Equals(other._reflectedType))) - { - return false; - } - - return true; - } - - public sealed override int GetHashCode() - { - int hashCode = _reflectedType.GetHashCode(); - hashCode ^= _underlyingPropertyInfo.GetHashCode(); - return hashCode; - } - - public sealed override Object GetConstantValue() - { - return _underlyingPropertyInfo.GetConstantValue(); - } - - public sealed override MethodInfo GetMethod - { - get - { - MethodInfo accessor = _underlyingPropertyInfo.GetMethod; - return Filter(accessor); - } - } - - public sealed override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture) - { - if (GetMethod == null) - { - throw new ArgumentException(SR.Arg_GetMethNotFnd); - } - - return _underlyingPropertyInfo.GetValue(obj, invokeAttr, binder, index, culture); - } - - public sealed override Module Module - { - get { return _underlyingPropertyInfo.Module; } - } - - public sealed override String ToString() - { - return _underlyingPropertyInfo.ToString(); - } - - public sealed override MethodInfo SetMethod - { - get - { - MethodInfo accessor = _underlyingPropertyInfo.SetMethod; - return Filter(accessor); - } - } - - public sealed override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture) - { - if (SetMethod == null) - { - throw new ArgumentException(SR.Arg_SetMethNotFnd); - } - - _underlyingPropertyInfo.SetValue(obj, value, invokeAttr, binder, index, culture); - } - - public sealed override MemberTypes MemberType { get { return MemberTypes.Property; } } - - public sealed override MethodInfo[] GetAccessors(bool nonPublic) - { - MethodInfo[] accessors = _underlyingPropertyInfo.GetAccessors(nonPublic); - MethodInfo[] survivors = new MethodInfo[accessors.Length]; - int numSurvivors = 0; - for (int i = 0; i < accessors.Length; i++) - { - MethodInfo survivor = Filter(accessors[i]); - if (survivor != null) - { - survivors[numSurvivors++] = survivor; - } - } - Array.Resize(ref survivors, numSurvivors); - return survivors; - } - - public sealed override MethodInfo GetGetMethod(bool nonPublic) - { - MethodInfo accessor = _underlyingPropertyInfo.GetGetMethod(nonPublic); - return Filter(accessor); - } - - public sealed override MethodInfo GetSetMethod(bool nonPublic) - { - MethodInfo accessor = _underlyingPropertyInfo.GetSetMethod(nonPublic); - return Filter(accessor); - } - - public sealed override object[] GetCustomAttributes(bool inherit) - { - return _underlyingPropertyInfo.GetCustomAttributes(inherit); - } - - public sealed override object[] GetCustomAttributes(Type attributeType, bool inherit) - { - return _underlyingPropertyInfo.GetCustomAttributes(attributeType, inherit); - } - - public sealed override bool IsDefined(Type attributeType, bool inherit) - { - return _underlyingPropertyInfo.IsDefined(attributeType, inherit); - } - - public sealed override Type ReflectedType - { - get { return _underlyingPropertyInfo.ReflectedType; } - } - - public sealed override IList<CustomAttributeData> GetCustomAttributesData() - { - return _underlyingPropertyInfo.GetCustomAttributesData(); - } - - public sealed override Type[] GetOptionalCustomModifiers() - { - return _underlyingPropertyInfo.GetOptionalCustomModifiers(); - } - - public sealed override object GetRawConstantValue() - { - return _underlyingPropertyInfo.GetRawConstantValue(); - } - - public sealed override Type[] GetRequiredCustomModifiers() - { - return _underlyingPropertyInfo.GetRequiredCustomModifiers(); - } - - public sealed override int MetadataToken - { - get { return _underlyingPropertyInfo.MetadataToken; } - } - -#if DEBUG - public sealed override object GetValue(object obj, object[] index) - { - return base.GetValue(obj, index); - } - - public sealed override void SetValue(object obj, object value, object[] index) - { - base.SetValue(obj, value, index); - } -#endif - - private MethodInfo Filter(MethodInfo accessor) - { - // - // For desktop compat, hide inherited accessors that are marked private. - // - // Q: Why don't we also hide cross-assembly "internal" accessors? - // A: That inconsistency is also desktop-compatible. - // - if (accessor == null || accessor.IsPrivate) - { - return null; - } - - return accessor; - } - } -} - diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/MemberPolicies.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/MemberPolicies.cs index 95535cf2e..aafed62c3 100644 --- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/MemberPolicies.cs +++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/MemberPolicies.cs @@ -65,15 +65,6 @@ namespace System.Reflection.Runtime.BindingFlagSupport public abstract bool IsSuppressedByMoreDerivedMember(M member, M[] priorMembers, int startIndex, int endIndex); // - // Policy to create a wrapper MemberInfo (if appropriate). This is due to the fact that MemberInfo's actually have their identity - // tied to the type they were queried off of and this unfortunate fact shows up in certain api behaviors. - // - public virtual M GetInheritedMemberInfo(M underlyingMemberInfo, Type reflectedType) - { - return underlyingMemberInfo; - } - - // // Helper method for determining whether two methods are signature-compatible for the purpose of implicit overriding. // protected static bool AreNamesAndSignaturesEqual(MethodInfo method1, MethodInfo method2) @@ -313,6 +304,19 @@ namespace System.Reflection.Runtime.BindingFlagSupport public sealed override void GetMemberAttributes(PropertyInfo member, out MethodAttributes visibility, out bool isStatic, out bool isVirtual, out bool isNewSlot) { MethodInfo accessorMethod = GetAccessorMethod(member); + if (accessorMethod == null) + { + // If we got here, this is a inherited PropertyInfo that only had private accessors and is now refusing to give them out + // because that's what the rules of inherited PropertyInfo's are. Such a PropertyInfo is also considered private and will never be + // given out of a Type.GetProperty() call. So all we have to do is set its visibility to Private and it will get filtered out. + // Other values need to be set to satisify C# but they are meaningless. + visibility = MethodAttributes.Private; + isStatic = false; + isVirtual = false; + isNewSlot = true; + return; + } + MethodAttributes methodAttributes = accessorMethod.Attributes; visibility = methodAttributes & MethodAttributes.MemberAccessMask; isStatic = (0 != (methodAttributes & MethodAttributes.Static)); @@ -346,11 +350,6 @@ namespace System.Reflection.Runtime.BindingFlagSupport return false; } - public sealed override PropertyInfo GetInheritedMemberInfo(PropertyInfo underlyingMemberInfo, Type reflectedType) - { - return new InheritedPropertyInfo(underlyingMemberInfo, reflectedType); - } - private MethodInfo GetAccessorMethod(PropertyInfo property) { MethodInfo accessor = property.GetMethod; diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/QueriedMemberList.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/QueriedMemberList.cs index 7b04093b9..935facd0b 100644 --- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/QueriedMemberList.cs +++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/QueriedMemberList.cs @@ -137,14 +137,7 @@ namespace System.Reflection.Runtime.BindingFlagSupport allFlagsThatMustMatch |= BindingFlags.FlattenHierarchy; allFlagsThatMustMatch |= ((visibility == MethodAttributes.Public) ? BindingFlags.Public : BindingFlags.NonPublic); - if (inBaseClass) - { - queriedMembers.Add(policies.GetInheritedMemberInfo(member, reflectedType), allFlagsThatMustMatch); - } - else - { - queriedMembers.Add(member, allFlagsThatMustMatch); - } + queriedMembers.Add(member, allFlagsThatMustMatch); } if (!inBaseClass) diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DefaultDispenserPolicy.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DefaultDispenserPolicy.cs index bacda5a42..880c1b3af 100644 --- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DefaultDispenserPolicy.cs +++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DefaultDispenserPolicy.cs @@ -14,9 +14,6 @@ namespace System.Reflection.Runtime.Dispensers { public sealed override DispenserAlgorithm GetAlgorithm(DispenserScenario scenario) { -#if TEST_CODEGEN_OPTIMIZATION - return DispenserAlgorithm.CreateAlways; -#else switch (scenario) { // Assembly + NamespaceTypeName to Type @@ -38,8 +35,6 @@ namespace System.Reflection.Runtime.Dispensers default: return DispenserAlgorithm.CreateAlways; } -#endif //!TEST_CODEGEN_OPTIMIZATION - } } } diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/EventInfos/RuntimeEventInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/EventInfos/RuntimeEventInfo.cs index 82b3facf4..1b17da567 100644 --- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/EventInfos/RuntimeEventInfo.cs +++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/EventInfos/RuntimeEventInfo.cs @@ -45,11 +45,12 @@ namespace System.Reflection.Runtime.EventInfos // // We don't report any DeclaredMembers for arrays or generic parameters so those don't apply. // - private RuntimeEventInfo(EventHandle eventHandle, RuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo) + private RuntimeEventInfo(EventHandle eventHandle, RuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo, RuntimeTypeInfo reflectedType) { _eventHandle = eventHandle; _definingTypeInfo = definingTypeInfo; _contextTypeInfo = contextTypeInfo; + _reflectedType = reflectedType; _reader = definingTypeInfo.Reader; _event = eventHandle.GetEvent(_reader); } @@ -68,7 +69,7 @@ namespace System.Reflection.Runtime.EventInfos MethodSemantics methodSemantics = methodSemanticsHandle.GetMethodSemantics(_reader); if (methodSemantics.Attributes == MethodSemanticsAttributes.AddOn) { - return RuntimeNamedMethodInfo.GetRuntimeNamedMethodInfo(methodSemantics.Method, _definingTypeInfo, _contextTypeInfo); + return RuntimeNamedMethodInfo.GetRuntimeNamedMethodInfo(methodSemantics.Method, _definingTypeInfo, _contextTypeInfo, _reflectedType); } } throw new BadImageFormatException(); // Added is a required method. @@ -123,6 +124,8 @@ namespace System.Reflection.Runtime.EventInfos return false; if (!(_contextTypeInfo.Equals(other._contextTypeInfo))) return false; + if (!(_reflectedType.Equals(other._reflectedType))) + return false; return true; } @@ -168,6 +171,14 @@ namespace System.Reflection.Runtime.EventInfos } } + public sealed override Type ReflectedType + { + get + { + return _reflectedType; + } + } + public sealed override MethodInfo RaiseMethod { get @@ -182,7 +193,7 @@ namespace System.Reflection.Runtime.EventInfos MethodSemantics methodSemantics = methodSemanticsHandle.GetMethodSemantics(_reader); if (methodSemantics.Attributes == MethodSemanticsAttributes.Fire) { - return RuntimeNamedMethodInfo.GetRuntimeNamedMethodInfo(methodSemantics.Method, _definingTypeInfo, _contextTypeInfo); + return RuntimeNamedMethodInfo.GetRuntimeNamedMethodInfo(methodSemantics.Method, _definingTypeInfo, _contextTypeInfo, _reflectedType); } } return null; @@ -203,7 +214,7 @@ namespace System.Reflection.Runtime.EventInfos MethodSemantics methodSemantics = methodSemanticsHandle.GetMethodSemantics(_reader); if (methodSemantics.Attributes == MethodSemanticsAttributes.RemoveOn) { - return RuntimeNamedMethodInfo.GetRuntimeNamedMethodInfo(methodSemantics.Method, _definingTypeInfo, _contextTypeInfo); + return RuntimeNamedMethodInfo.GetRuntimeNamedMethodInfo(methodSemantics.Method, _definingTypeInfo, _contextTypeInfo, _reflectedType); } } throw new BadImageFormatException(); // Removed is a required method. @@ -256,6 +267,7 @@ namespace System.Reflection.Runtime.EventInfos private readonly RuntimeNamedTypeInfo _definingTypeInfo; private readonly EventHandle _eventHandle; private readonly RuntimeTypeInfo _contextTypeInfo; + private readonly RuntimeTypeInfo _reflectedType; private readonly MetadataReader _reader; private readonly Event _event; diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/FieldInfos/RuntimeFieldInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/FieldInfos/RuntimeFieldInfo.cs index a7aebcd76..7be9abd89 100644 --- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/FieldInfos/RuntimeFieldInfo.cs +++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/FieldInfos/RuntimeFieldInfo.cs @@ -48,11 +48,12 @@ namespace System.Reflection.Runtime.FieldInfos // // We don't report any DeclaredMembers for arrays or generic parameters so those don't apply. // - private RuntimeFieldInfo(FieldHandle fieldHandle, RuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo) + private RuntimeFieldInfo(FieldHandle fieldHandle, RuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo, RuntimeTypeInfo reflectedType) { _fieldHandle = fieldHandle; _definingTypeInfo = definingTypeInfo; _contextTypeInfo = contextTypeInfo; + _reflectedType = reflectedType; _reader = definingTypeInfo.Reader; _field = fieldHandle.GetField(_reader); } @@ -143,6 +144,14 @@ namespace System.Reflection.Runtime.FieldInfos } } + public sealed override Type ReflectedType + { + get + { + return _reflectedType; + } + } + public sealed override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture) { #if ENABLE_REFLECTION_TRACE @@ -175,6 +184,8 @@ namespace System.Reflection.Runtime.FieldInfos return false; if (!(_contextTypeInfo.Equals(other._contextTypeInfo))) return false; + if (!(_reflectedType.Equals(other._reflectedType))) + return false; return true; } @@ -265,6 +276,7 @@ namespace System.Reflection.Runtime.FieldInfos private readonly RuntimeNamedTypeInfo _definingTypeInfo; private readonly FieldHandle _fieldHandle; private readonly RuntimeTypeInfo _contextTypeInfo; + private readonly RuntimeTypeInfo _reflectedType; private readonly MetadataReader _reader; private readonly Field _field; diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/ApiToDoList.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/ApiToDoList.cs index 9ccef7c96..b169e6a62 100644 --- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/ApiToDoList.cs +++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/ApiToDoList.cs @@ -39,7 +39,6 @@ namespace System.Reflection.Runtime.MethodInfos { public sealed override MethodBody GetMethodBody() { throw new NotImplementedException(); } public sealed override RuntimeMethodHandle MethodHandle { get { throw new NotImplementedException(); } } - public sealed override Type ReflectedType { get { throw new NotImplementedException(); } } } } @@ -55,7 +54,6 @@ namespace System.Reflection.Runtime.EventInfos internal sealed partial class RuntimeEventInfo { public sealed override MethodInfo[] GetOtherMethods(bool nonPublic) { throw new NotImplementedException(); } - public sealed override Type ReflectedType { get { throw new NotImplementedException(); } } } } @@ -66,7 +64,6 @@ namespace System.Reflection.Runtime.FieldInfos public sealed override RuntimeFieldHandle FieldHandle { get { throw new NotImplementedException(); } } public sealed override Type[] GetOptionalCustomModifiers() { throw new NotImplementedException(); } public sealed override Type[] GetRequiredCustomModifiers() { throw new NotImplementedException(); } - public sealed override Type ReflectedType { get { throw new NotImplementedException(); } } } } @@ -76,7 +73,6 @@ namespace System.Reflection.Runtime.MethodInfos { public sealed override MethodBody GetMethodBody() { throw new NotImplementedException(); } public sealed override RuntimeMethodHandle MethodHandle { get { throw new NotImplementedException(); } } - public sealed override Type ReflectedType { get { throw new NotImplementedException(); } } } } @@ -115,7 +111,6 @@ namespace System.Reflection.Runtime.PropertyInfos { internal sealed partial class RuntimePropertyInfo { - public sealed override Type ReflectedType { get { throw new NotImplementedException(); } } public sealed override Type[] GetOptionalCustomModifiers() { throw new NotImplementedException(); } public sealed override Type[] GetRequiredCustomModifiers() { throw new NotImplementedException(); } } @@ -126,6 +121,5 @@ namespace System.Reflection.Runtime.TypeInfos internal abstract partial class RuntimeTypeInfo { public sealed override object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters) { throw new NotImplementedException(); } - public sealed override Type ReflectedType { get { throw new NotImplementedException(); } } } } diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/Dispensers.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/Dispensers.cs index 4edd86e9d..e1d327f71 100644 --- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/Dispensers.cs +++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/Dispensers.cs @@ -169,9 +169,9 @@ namespace System.Reflection.Runtime.FieldInfos //----------------------------------------------------------------------------------------------------------- internal sealed partial class RuntimeFieldInfo { - internal static RuntimeFieldInfo GetRuntimeFieldInfo(FieldHandle fieldHandle, RuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo) + internal static RuntimeFieldInfo GetRuntimeFieldInfo(FieldHandle fieldHandle, RuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo, RuntimeTypeInfo reflectedType) { - return new RuntimeFieldInfo(fieldHandle, definingTypeInfo, contextTypeInfo).WithDebugName(); + return new RuntimeFieldInfo(fieldHandle, definingTypeInfo, contextTypeInfo, reflectedType).WithDebugName(); } } } @@ -205,9 +205,9 @@ namespace System.Reflection.Runtime.MethodInfos //----------------------------------------------------------------------------------------------------------- internal sealed partial class RuntimeNamedMethodInfo : RuntimeMethodInfo { - internal static RuntimeNamedMethodInfo GetRuntimeNamedMethodInfo(MethodHandle methodHandle, RuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo) + internal static RuntimeNamedMethodInfo GetRuntimeNamedMethodInfo(MethodHandle methodHandle, RuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo, RuntimeTypeInfo reflectedType) { - RuntimeNamedMethodInfo method = new RuntimeNamedMethodInfo(methodHandle, definingTypeInfo, contextTypeInfo); + RuntimeNamedMethodInfo method = new RuntimeNamedMethodInfo(methodHandle, definingTypeInfo, contextTypeInfo, reflectedType); method.WithDebugName(); return method; } @@ -243,9 +243,9 @@ namespace System.Reflection.Runtime.PropertyInfos //----------------------------------------------------------------------------------------------------------- internal sealed partial class RuntimePropertyInfo { - internal static RuntimePropertyInfo GetRuntimePropertyInfo(PropertyHandle propertyHandle, RuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo) + internal static RuntimePropertyInfo GetRuntimePropertyInfo(PropertyHandle propertyHandle, RuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo, RuntimeTypeInfo reflectedType) { - return new RuntimePropertyInfo(propertyHandle, definingTypeInfo, contextTypeInfo).WithDebugName(); + return new RuntimePropertyInfo(propertyHandle, definingTypeInfo, contextTypeInfo, reflectedType).WithDebugName(); } } } @@ -257,9 +257,9 @@ namespace System.Reflection.Runtime.EventInfos //----------------------------------------------------------------------------------------------------------- internal sealed partial class RuntimeEventInfo { - internal static RuntimeEventInfo GetRuntimeEventInfo(EventHandle eventHandle, RuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo) + internal static RuntimeEventInfo GetRuntimeEventInfo(EventHandle eventHandle, RuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo, RuntimeTypeInfo reflectedType) { - return new RuntimeEventInfo(eventHandle, definingTypeInfo, contextTypeInfo).WithDebugName(); + return new RuntimeEventInfo(eventHandle, definingTypeInfo, contextTypeInfo, reflectedType).WithDebugName(); } } } diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/ReflectionCoreCallbacksImplementation.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/ReflectionCoreCallbacksImplementation.cs index be4735b3c..c47091ff1 100644 --- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/ReflectionCoreCallbacksImplementation.cs +++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/ReflectionCoreCallbacksImplementation.cs @@ -162,7 +162,10 @@ namespace System.Reflection.Runtime.General RuntimeTypeInfo contextTypeInfo = declaringTypeHandle.GetTypeForRuntimeTypeHandle(); RuntimeNamedTypeInfo definingTypeInfo = contextTypeInfo.AnchoringTypeDefinitionForDeclaredMembers; MetadataReader reader = definingTypeInfo.Reader; - return RuntimeFieldInfo.GetRuntimeFieldInfo(fieldHandle, definingTypeInfo, contextTypeInfo); + + // RuntimeFieldHandles always yield FieldInfo's whose ReflectedType equals the DeclaringType. + RuntimeTypeInfo reflectedType = contextTypeInfo; + return RuntimeFieldInfo.GetRuntimeFieldInfo(fieldHandle, definingTypeInfo, contextTypeInfo, reflectedType); } } } diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructedGenericMethodInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructedGenericMethodInfo.cs index e025a7d73..6cb0726c3 100644 --- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructedGenericMethodInfo.cs +++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructedGenericMethodInfo.cs @@ -115,6 +115,14 @@ namespace System.Reflection.Runtime.MethodInfos } } + public sealed override Type ReflectedType + { + get + { + return _genericMethodDefinition.ReflectedType; + } + } + public sealed override String ToString() { return _genericMethodDefinition.ComputeToString(this); diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructorInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructorInfo.cs index 8a1959ae8..ddfba9594 100644 --- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructorInfo.cs +++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructorInfo.cs @@ -148,6 +148,15 @@ namespace System.Reflection.Runtime.MethodInfos public abstract override int GetHashCode(); + public sealed override Type ReflectedType + { + get + { + // Constructors are always looked up as if BindingFlags.DeclaredOnly were specified. Thus, the ReflectedType will always be the DeclaringType. + return DeclaringType; + } + } + public abstract override String ToString(); protected MethodInvoker MethodInvoker diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodInfo.cs index c4b0da1cf..95b4c780a 100644 --- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodInfo.cs +++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodInfo.cs @@ -206,6 +206,8 @@ namespace System.Reflection.Runtime.MethodInfos } } + public abstract override Type ReflectedType { get; } + public sealed override ParameterInfo ReturnParameter { get diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeNamedMethodInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeNamedMethodInfo.cs index 73d584d42..118fdea04 100644 --- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeNamedMethodInfo.cs +++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeNamedMethodInfo.cs @@ -42,10 +42,11 @@ namespace System.Reflection.Runtime.MethodInfos // // We don't report any DeclaredMembers for arrays or generic parameters so those don't apply. // - private RuntimeNamedMethodInfo(MethodHandle methodHandle, RuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo) + private RuntimeNamedMethodInfo(MethodHandle methodHandle, RuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo, RuntimeTypeInfo reflectedType) : base() { _common = new RuntimeMethodCommon(methodHandle, definingTypeInfo, contextTypeInfo); + _reflectedType = reflectedType; } public sealed override MethodAttributes Attributes @@ -146,6 +147,14 @@ namespace System.Reflection.Runtime.MethodInfos } } + public sealed override Type ReflectedType + { + get + { + return _reflectedType; + } + } + public sealed override String ToString() { return ComputeToString(this); @@ -156,7 +165,11 @@ namespace System.Reflection.Runtime.MethodInfos RuntimeNamedMethodInfo other = obj as RuntimeNamedMethodInfo; if (other == null) return false; - return _common.Equals(other._common); + if (!_common.Equals(other._common)) + return false; + if (!(_reflectedType.Equals(other._reflectedType))) + return false; + return true; } public sealed override int GetHashCode() @@ -232,7 +245,14 @@ namespace System.Reflection.Runtime.MethodInfos { // Desktop compat: Constructed generic types and their generic type definitions share the same Type objects for method generic parameters. RuntimeNamedTypeInfo genericTypeDefinition = DeclaringType.GetGenericTypeDefinition().CastToRuntimeNamedTypeInfo(); - owningMethod = RuntimeNamedMethodInfo.GetRuntimeNamedMethodInfo(Handle, genericTypeDefinition, genericTypeDefinition); + owningMethod = RuntimeNamedMethodInfo.GetRuntimeNamedMethodInfo(Handle, genericTypeDefinition, genericTypeDefinition, genericTypeDefinition); + } + else + { + // Desktop compat: DeclaringMethod always returns a MethodInfo whose ReflectedType is equal to DeclaringType. + if (!_reflectedType.Equals(_common.DeclaringType)) + owningMethod = RuntimeNamedMethodInfo.GetRuntimeNamedMethodInfo(_common.MethodHandle, _common.DefiningTypeInfo, _common.ContextTypeInfo, _common.DeclaringType); + } RuntimeTypeInfo genericParameterType = RuntimeGenericParameterTypeInfoForMethods.GetRuntimeGenericParameterTypeInfoForMethods(owningMethod, owningMethod._common.Reader, genericParameterHandle); genericTypeParameters[i++] = genericParameterType; @@ -250,5 +270,6 @@ namespace System.Reflection.Runtime.MethodInfos } private readonly RuntimeMethodCommon _common; + private readonly RuntimeTypeInfo _reflectedType; } } diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticMethodInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticMethodInfo.cs index 4010ccb98..4159dfdb8 100644 --- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticMethodInfo.cs +++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticMethodInfo.cs @@ -115,6 +115,16 @@ namespace System.Reflection.Runtime.MethodInfos } } + public sealed override Type ReflectedType + { + get + { + // The only synthetic methods come from array types which can never be inherited from. So unless that changes, + // we don't provide a way to specify the ReflectedType. + return DeclaringType; + } + } + public sealed override String ToString() { return RuntimeMethodCommon.ComputeToString(this, Array.Empty<RuntimeTypeInfo>(), RuntimeParameters, RuntimeReturnParameter); diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/PropertyInfos/RuntimePropertyInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/PropertyInfos/RuntimePropertyInfo.cs index 34edd9a3b..c696dccb6 100644 --- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/PropertyInfos/RuntimePropertyInfo.cs +++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/PropertyInfos/RuntimePropertyInfo.cs @@ -49,11 +49,12 @@ namespace System.Reflection.Runtime.PropertyInfos // // We don't report any DeclaredMembers for arrays or generic parameters so those don't apply. // - private RuntimePropertyInfo(PropertyHandle propertyHandle, RuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo) + private RuntimePropertyInfo(PropertyHandle propertyHandle, RuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo, RuntimeTypeInfo reflectedType) { _propertyHandle = propertyHandle; _definingTypeInfo = definingTypeInfo; _contextTypeInfo = contextTypeInfo; + _reflectedType = reflectedType; _reader = definingTypeInfo.Reader; _property = propertyHandle.GetProperty(_reader); } @@ -124,6 +125,8 @@ namespace System.Reflection.Runtime.PropertyInfos return false; if (!(_contextTypeInfo.Equals(other._contextTypeInfo))) return false; + if (!(_reflectedType.Equals(other._reflectedType))) + return false; return true; } @@ -247,6 +250,14 @@ namespace System.Reflection.Runtime.PropertyInfos } } + public sealed override Type ReflectedType + { + get + { + return _reflectedType; + } + } + public sealed override MethodInfo SetMethod { get @@ -340,7 +351,7 @@ namespace System.Reflection.Runtime.PropertyInfos MethodHandle getterHandle; if (GetAccessor(MethodSemanticsAttributes.Getter, out getterHandle)) { - return RuntimeNamedMethodInfo.GetRuntimeNamedMethodInfo(getterHandle, _definingTypeInfo, _contextTypeInfo); + return RuntimeNamedMethodInfo.GetRuntimeNamedMethodInfo(getterHandle, _definingTypeInfo, _contextTypeInfo, _reflectedType); } return null; } @@ -353,7 +364,7 @@ namespace System.Reflection.Runtime.PropertyInfos MethodHandle setterHandle; if (GetAccessor(MethodSemanticsAttributes.Setter, out setterHandle)) { - return RuntimeNamedMethodInfo.GetRuntimeNamedMethodInfo(setterHandle, _definingTypeInfo, _contextTypeInfo); + return RuntimeNamedMethodInfo.GetRuntimeNamedMethodInfo(setterHandle, _definingTypeInfo, _contextTypeInfo, _reflectedType); } return null; } @@ -361,12 +372,22 @@ namespace System.Reflection.Runtime.PropertyInfos private bool GetAccessor(MethodSemanticsAttributes methodSemanticsAttribute, out MethodHandle methodHandle) { + bool inherited = !_reflectedType.Equals(_contextTypeInfo); + foreach (MethodSemanticsHandle methodSemanticsHandle in _property.MethodSemantics) { MethodSemantics methodSemantics = methodSemanticsHandle.GetMethodSemantics(_reader); if (methodSemantics.Attributes == methodSemanticsAttribute) { methodHandle = methodSemantics.Method; + + if (inherited) + { + MethodAttributes flags = methodHandle.GetMethod(_reader).Flags; + if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private) + continue; + } + return true; } } @@ -394,6 +415,7 @@ namespace System.Reflection.Runtime.PropertyInfos private readonly RuntimeNamedTypeInfo _definingTypeInfo; private readonly PropertyHandle _propertyHandle; private readonly RuntimeTypeInfo _contextTypeInfo; + private readonly RuntimeTypeInfo _reflectedType; private readonly MetadataReader _reader; private readonly Property _property; diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.CoreGetDeclared.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.CoreGetDeclared.cs index 4f69aa03d..f043d3044 100644 --- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.CoreGetDeclared.cs +++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.CoreGetDeclared.cs @@ -73,7 +73,7 @@ namespace System.Reflection.Runtime.TypeInfos continue; if (optionalNameFilter == null || optionalNameFilter.Matches(method.Name, reader)) - yield return RuntimeNamedMethodInfo.GetRuntimeNamedMethodInfo(methodHandle, definingType, this); + yield return RuntimeNamedMethodInfo.GetRuntimeNamedMethodInfo(methodHandle, definingType, this, reflectedType); } } @@ -93,7 +93,7 @@ namespace System.Reflection.Runtime.TypeInfos foreach (EventHandle eventHandle in definingType.DeclaredEventHandles) { if (optionalNameFilter == null || optionalNameFilter.Matches(eventHandle.GetEvent(reader).Name, reader)) - yield return RuntimeEventInfo.GetRuntimeEventInfo(eventHandle, definingType, this); + yield return RuntimeEventInfo.GetRuntimeEventInfo(eventHandle, definingType, this, reflectedType); } } } @@ -107,7 +107,7 @@ namespace System.Reflection.Runtime.TypeInfos foreach (FieldHandle fieldHandle in definingType.DeclaredFieldHandles) { if (optionalNameFilter == null || optionalNameFilter.Matches(fieldHandle.GetField(reader).Name, reader)) - yield return RuntimeFieldInfo.GetRuntimeFieldInfo(fieldHandle, definingType, this); + yield return RuntimeFieldInfo.GetRuntimeFieldInfo(fieldHandle, definingType, this, reflectedType); } } } @@ -121,7 +121,7 @@ namespace System.Reflection.Runtime.TypeInfos foreach (PropertyHandle propertyHandle in definingType.DeclaredPropertyHandles) { if (optionalNameFilter == null || optionalNameFilter.Matches(propertyHandle.GetProperty(reader).Name, reader)) - yield return RuntimePropertyInfo.GetRuntimePropertyInfo(propertyHandle, definingType, this); + yield return RuntimePropertyInfo.GetRuntimePropertyInfo(propertyHandle, definingType, this, reflectedType); } } } diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.cs index 95ec6191f..7aa583957 100644 --- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.cs +++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.cs @@ -519,6 +519,16 @@ namespace System.Reflection.Runtime.TypeInfos } } + public sealed override Type ReflectedType + { + get + { + // Desktop compat: For types, ReflectedType == DeclaringType. Nested types are always looked up as BindingFlags.DeclaredOnly was passed. + // For non-nested types, the concept of a ReflectedType doesn't even make sense. + return DeclaringType; + } + } + public abstract override StructLayoutAttribute StructLayoutAttribute { get; } public abstract override string ToString(); diff --git a/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/MethodInvokers/NullableInstanceMethodInvoker.cs b/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/MethodInvokers/NullableInstanceMethodInvoker.cs index 6a74f6284..1753e5c29 100644 --- a/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/MethodInvokers/NullableInstanceMethodInvoker.cs +++ b/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/MethodInvokers/NullableInstanceMethodInvoker.cs @@ -34,7 +34,7 @@ namespace Internal.Reflection.Execution.MethodInvokers public NullableInstanceMethodInvoker(MetadataReader reader, MethodHandle methodHandle, RuntimeTypeHandle nullableTypeHandle, MethodInvokeInfo methodInvokeInfo) { _id = NullableMethodId.None; - s_nullableTypeHandle = nullableTypeHandle; + _nullableTypeHandle = nullableTypeHandle; Method method = methodHandle.GetMethod(reader); if (MethodAttributes.Public == (method.Flags & MethodAttributes.MemberAccessMask)) { @@ -119,7 +119,7 @@ namespace Internal.Reflection.Execution.MethodInvokers // where the constructor is responsible for both the allocation and initialization. Fortunately, we only have to return the boxed // version of Nullable<T> which conveniently happens to be equal to the value we were passed in. CheckArgumentCount(arguments, 1); - RuntimeTypeHandle theT = RuntimeAugments.GetNullableType(s_nullableTypeHandle); + RuntimeTypeHandle theT = RuntimeAugments.GetNullableType(_nullableTypeHandle); Object argument = RuntimeAugments.CheckArgument(arguments[0], theT); return argument; } @@ -139,14 +139,14 @@ namespace Internal.Reflection.Execution.MethodInvokers CheckArgumentCount(arguments, 0); if (hasValue) return value; - RuntimeTypeHandle theT = RuntimeAugments.GetNullableType(s_nullableTypeHandle); + RuntimeTypeHandle theT = RuntimeAugments.GetNullableType(_nullableTypeHandle); return RuntimeAugments.NewObject(theT); } case NullableMethodId.GetValueOrDefault_1: { CheckArgumentCount(arguments, 1); - RuntimeTypeHandle theT = RuntimeAugments.GetNullableType(s_nullableTypeHandle); + RuntimeTypeHandle theT = RuntimeAugments.GetNullableType(_nullableTypeHandle); Object defaultValue = RuntimeAugments.CheckArgument(arguments[0], theT); return hasValue ? value : defaultValue; } @@ -183,8 +183,8 @@ namespace Internal.Reflection.Execution.MethodInvokers None = -1, } - private NullableMethodId _id; - private static RuntimeTypeHandle s_nullableTypeHandle; + private readonly NullableMethodId _id; + private readonly RuntimeTypeHandle _nullableTypeHandle; // type handle of a specific instantiation of Nullable<> } } |