diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml b/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml index b1a9381f3fd415..0abedd830a6b14 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml @@ -653,14 +653,6 @@ CP0001 T:Internal.Metadata.NativeFormat.UInt64Collection - - CP0001 - T:Internal.Reflection.Augments.ReflectionAugments - - - CP0001 - T:Internal.Reflection.Augments.ReflectionCoreCallbacks - CP0001 T:Internal.Reflection.Core.AssemblyBinder diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Augments/ReflectionAugments.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Augments/ReflectionAugments.cs index 5ed208a4d59815..86fbbcba782fe5 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Augments/ReflectionAugments.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Augments/ReflectionAugments.cs @@ -17,30 +17,31 @@ // Reflection.Core.dll using System; +using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; -using System.Numerics; using System.Reflection; - +using System.Reflection.Runtime.Assemblies; +using System.Reflection.Runtime.BindingFlagSupport; +using System.Reflection.Runtime.FieldInfos; +using System.Reflection.Runtime.FieldInfos.NativeFormat; +using System.Reflection.Runtime.General; +using System.Reflection.Runtime.MethodInfos; +using System.Reflection.Runtime.TypeInfos; +using System.Reflection.Runtime.TypeInfos.NativeFormat; + +using Internal.Metadata.NativeFormat; +using Internal.Reflection.Core.Execution; using Internal.Runtime; +using Internal.Runtime.Augments; using EETypeElementType = Internal.Runtime.EETypeElementType; namespace Internal.Reflection.Augments { - public static class ReflectionAugments + internal static class ReflectionAugments { - // - // One time start up initialization - called by Reflection.Core.dll to provide System.Reflection with a way to call back - // into Reflection.Core.dll. - // - public static void Initialize(ReflectionCoreCallbacks reflectionCoreCallbacks) - { - Debug.Assert(s_reflectionCoreCallbacks == null); - s_reflectionCoreCallbacks = reflectionCoreCallbacks; - } - internal static unsafe TypeCode GetRuntimeTypeCode(RuntimeType type) { Debug.Assert(type != null); @@ -97,82 +98,436 @@ public static TypeLoadException CreateTypeLoadException(string message, string t return new TypeLoadException(message, typeName); } - internal static ReflectionCoreCallbacks ReflectionCoreCallbacks + public static Assembly Load(AssemblyName assemblyRef, bool throwOnFileNotFound) + { + ArgumentNullException.ThrowIfNull(assemblyRef); + + if (throwOnFileNotFound) + return RuntimeAssemblyInfo.GetRuntimeAssembly(assemblyRef.ToRuntimeAssemblyName()); + else + return RuntimeAssemblyInfo.GetRuntimeAssemblyIfExists(assemblyRef.ToRuntimeAssemblyName()); + } + + public static Assembly Load(ReadOnlySpan rawAssembly, ReadOnlySpan pdbSymbolStore) + { + if (rawAssembly.IsEmpty) + throw new ArgumentNullException(nameof(rawAssembly)); + + return RuntimeAssemblyInfo.GetRuntimeAssemblyFromByteArray(rawAssembly, pdbSymbolStore); + } + + public static Assembly Load(string assemblyPath) { - get + ArgumentNullException.ThrowIfNull(assemblyPath); + + return RuntimeAssemblyInfo.GetRuntimeAssemblyFromPath(assemblyPath); + } + + // + // This overload of GetMethodForHandle only accepts handles for methods declared on non-generic types (the method, however, + // can be an instance of a generic method.) To resolve handles for methods declared on generic types, you must pass + // the declaring type explicitly using the two-argument overload of GetMethodFromHandle. + // + // This is a vestige from desktop generic sharing that got itself enshrined in the code generated by the C# compiler for Linq Expressions. + // + public static MethodBase GetMethodFromHandle(RuntimeMethodHandle runtimeMethodHandle) + { + ExecutionEnvironment executionEnvironment = ReflectionCoreExecution.ExecutionEnvironment; + QMethodDefinition methodHandle; + RuntimeTypeHandle declaringTypeHandle; + RuntimeTypeHandle[] genericMethodTypeArgumentHandles; + if (!executionEnvironment.TryGetMethodFromHandle(runtimeMethodHandle, out declaringTypeHandle, out methodHandle, out genericMethodTypeArgumentHandles)) + throw new ArgumentException(SR.Argument_InvalidHandle); + + MethodBase methodBase = ExecutionDomain.GetMethod(declaringTypeHandle, methodHandle, genericMethodTypeArgumentHandles); + if (methodBase.DeclaringType.IsConstructedGenericType) // For compat with desktop, insist that the caller pass us the declaring type to resolve members of generic types. + throw new ArgumentException(SR.Format(SR.Argument_MethodDeclaringTypeGeneric, methodBase)); + return methodBase; + } + + // + // This overload of GetMethodHandle can handle all method handles. + // + public static MethodBase GetMethodFromHandle(RuntimeMethodHandle runtimeMethodHandle, RuntimeTypeHandle declaringTypeHandle) + { + ExecutionEnvironment executionEnvironment = ReflectionCoreExecution.ExecutionEnvironment; + QMethodDefinition methodHandle; + RuntimeTypeHandle[] genericMethodTypeArgumentHandles; + if (!executionEnvironment.TryGetMethodFromHandleAndType(runtimeMethodHandle, declaringTypeHandle, out methodHandle, out genericMethodTypeArgumentHandles)) { - ReflectionCoreCallbacks callbacks = s_reflectionCoreCallbacks; - Debug.Assert(callbacks != null); - return callbacks; + // This may be a method declared on a non-generic type: this api accepts that too so try the other table. + RuntimeTypeHandle actualDeclaringTypeHandle; + if (!executionEnvironment.TryGetMethodFromHandle(runtimeMethodHandle, out actualDeclaringTypeHandle, out methodHandle, out genericMethodTypeArgumentHandles)) + throw new ArgumentException(SR.Argument_InvalidHandle); + if (!actualDeclaringTypeHandle.Equals(declaringTypeHandle)) + throw new ArgumentException(SR.Format(SR.Argument_ResolveMethodHandle, + declaringTypeHandle.GetRuntimeTypeInfoForRuntimeTypeHandle(), + actualDeclaringTypeHandle.GetRuntimeTypeInfoForRuntimeTypeHandle())); } + + MethodBase methodBase = ExecutionDomain.GetMethod(declaringTypeHandle, methodHandle, genericMethodTypeArgumentHandles); + return methodBase; } - internal static bool IsInitialized + // + // This overload of GetFieldForHandle only accepts handles for fields declared on non-generic types. To resolve handles for fields + // declared on generic types, you must pass the declaring type explicitly using the two-argument overload of GetFieldFromHandle. + // + // This is a vestige from desktop generic sharing that got itself enshrined in the code generated by the C# compiler for Linq Expressions. + // + public static FieldInfo GetFieldFromHandle(RuntimeFieldHandle runtimeFieldHandle) + { + ExecutionEnvironment executionEnvironment = ReflectionCoreExecution.ExecutionEnvironment; + FieldHandle fieldHandle; + RuntimeTypeHandle declaringTypeHandle; + if (!executionEnvironment.TryGetFieldFromHandle(runtimeFieldHandle, out declaringTypeHandle, out fieldHandle)) + throw new ArgumentException(SR.Argument_InvalidHandle); + + FieldInfo fieldInfo = GetFieldInfo(declaringTypeHandle, fieldHandle); + if (fieldInfo.DeclaringType.IsConstructedGenericType) // For compat with desktop, insist that the caller pass us the declaring type to resolve members of generic types. + throw new ArgumentException(SR.Format(SR.Argument_FieldDeclaringTypeGeneric, fieldInfo)); + return fieldInfo; + } + + // + // This overload of GetFieldHandle can handle all field handles. + // + public static FieldInfo GetFieldFromHandle(RuntimeFieldHandle runtimeFieldHandle, RuntimeTypeHandle declaringTypeHandle) { - get + ExecutionEnvironment executionEnvironment = ReflectionCoreExecution.ExecutionEnvironment; + FieldHandle fieldHandle; + if (!executionEnvironment.TryGetFieldFromHandleAndType(runtimeFieldHandle, declaringTypeHandle, out fieldHandle)) { - return s_reflectionCoreCallbacks != null; + // This may be a field declared on a non-generic type: this api accepts that too so try the other table. + RuntimeTypeHandle actualDeclaringTypeHandle; + if (!executionEnvironment.TryGetFieldFromHandle(runtimeFieldHandle, out actualDeclaringTypeHandle, out fieldHandle)) + throw new ArgumentException(SR.Argument_InvalidHandle); + if (!actualDeclaringTypeHandle.Equals(declaringTypeHandle)) + throw new ArgumentException(SR.Format(SR.Argument_ResolveFieldHandle, + declaringTypeHandle.GetRuntimeTypeInfoForRuntimeTypeHandle(), + actualDeclaringTypeHandle.GetRuntimeTypeInfoForRuntimeTypeHandle())); } + + FieldInfo fieldInfo = GetFieldInfo(declaringTypeHandle, fieldHandle); + return fieldInfo; } - private static ReflectionCoreCallbacks s_reflectionCoreCallbacks; - } + public static EventInfo GetImplicitlyOverriddenBaseClassEvent(EventInfo e) + { + return e.GetImplicitlyOverriddenBaseClassMember(EventPolicies.Instance); + } - // - // This class is implemented by Internal.Reflection.Core.dll and provides the actual implementation - // of Type.GetTypeInfo() and Assembly.Load(). - // - public abstract class ReflectionCoreCallbacks - { - public abstract Assembly Load(AssemblyName refName, bool throwOnFileNotFound); - public abstract Assembly Load(ReadOnlySpan rawAssembly, ReadOnlySpan pdbSymbolStore); - public abstract Assembly Load(string assemblyPath); + public static MethodInfo GetImplicitlyOverriddenBaseClassMethod(MethodInfo m) + { + return m.GetImplicitlyOverriddenBaseClassMember(MethodPolicies.Instance); + } + + public static PropertyInfo GetImplicitlyOverriddenBaseClassProperty(PropertyInfo p) + { + return p.GetImplicitlyOverriddenBaseClassMember(PropertyPolicies.Instance); + } - public abstract MethodBase GetMethodFromHandle(RuntimeMethodHandle runtimeMethodHandle); - public abstract MethodBase GetMethodFromHandle(RuntimeMethodHandle runtimeMethodHandle, RuntimeTypeHandle declaringTypeHandle); - public abstract FieldInfo GetFieldFromHandle(RuntimeFieldHandle runtimeFieldHandle); - public abstract FieldInfo GetFieldFromHandle(RuntimeFieldHandle runtimeFieldHandle, RuntimeTypeHandle declaringTypeHandle); + private static RuntimeFieldInfo GetFieldInfo(RuntimeTypeHandle declaringTypeHandle, FieldHandle fieldHandle) + { + RuntimeTypeInfo contextTypeInfo = declaringTypeHandle.GetRuntimeTypeInfoForRuntimeTypeHandle(); + NativeFormatRuntimeNamedTypeInfo definingTypeInfo = contextTypeInfo.AnchoringTypeDefinitionForDeclaredMembers.CastToNativeFormatRuntimeNamedTypeInfo(); - public abstract EventInfo GetImplicitlyOverriddenBaseClassEvent(EventInfo e); - public abstract MethodInfo GetImplicitlyOverriddenBaseClassMethod(MethodInfo m); - public abstract PropertyInfo GetImplicitlyOverriddenBaseClassProperty(PropertyInfo p); + // RuntimeFieldHandles always yield FieldInfo's whose ReflectedType equals the DeclaringType. + RuntimeTypeInfo reflectedType = contextTypeInfo; + return NativeFormatRuntimeFieldInfo.GetRuntimeFieldInfo(fieldHandle, definingTypeInfo, contextTypeInfo, reflectedType); + } - public abstract object ActivatorCreateInstance( + [DebuggerHidden] + [DebuggerStepThrough] + public static object ActivatorCreateInstance( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] - Type type, bool nonPublic); - public abstract object ActivatorCreateInstance( + Type type, bool nonPublic) + { + return ActivatorImplementation.CreateInstance(type, nonPublic); + } + + [DebuggerHidden] + [DebuggerStepThrough] + public static object ActivatorCreateInstance( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] - Type type, BindingFlags bindingAttr, Binder? binder, object?[]? args, CultureInfo? culture, object?[]? activationAttributes); + Type type, BindingFlags bindingAttr, Binder? binder, object?[]? args, CultureInfo? culture, object?[]? activationAttributes) + { + return ActivatorImplementation.CreateInstance(type, bindingAttr, binder, args, culture, activationAttributes); + } // V2 api: Creates open or closed delegates to static or instance methods - relaxed signature checking allowed. - public abstract Delegate CreateDelegate(Type type, object? firstArgument, MethodInfo method, bool throwOnBindFailure); + public static Delegate CreateDelegate(Type type, object firstArgument, MethodInfo method, bool throwOnBindFailure) + { + return CreateDelegateWorker(type, firstArgument, method, throwOnBindFailure, allowClosed: true); + } // V1 api: Creates open delegates to static or instance methods - relaxed signature checking allowed. - public abstract Delegate CreateDelegate(Type type, MethodInfo method, bool throwOnBindFailure); + public static Delegate CreateDelegate(Type type, MethodInfo method, bool throwOnBindFailure) + { + // This API existed in v1/v1.1 and only expected to create open + // instance delegates, so we forbid closed delegates for backward compatibility. + // But we'll allow relaxed signature checking and open static delegates because + // there's no ambiguity there (the caller would have to explicitly + // pass us a static method or a method with a non-exact signature + // and the only change in behavior from v1.1 there is that we won't + // fail the call). + return CreateDelegateWorker(type, null, method, throwOnBindFailure, allowClosed: false); + } + + private static Delegate CreateDelegateWorker(Type type, object firstArgument, MethodInfo method, bool throwOnBindFailure, bool allowClosed) + { + ArgumentNullException.ThrowIfNull(type); + ArgumentNullException.ThrowIfNull(method); + + if (!(type is RuntimeType runtimeDelegateType)) + throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(type)); + + if (!(method is RuntimeMethodInfo runtimeMethodInfo)) + throw new ArgumentException(SR.Argument_MustBeRuntimeMethodInfo, nameof(method)); + + RuntimeTypeInfo runtimeDelegateTypeInfo = runtimeDelegateType.GetRuntimeTypeInfo(); + + if (!runtimeDelegateTypeInfo.IsDelegate) + throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(type)); + + Delegate result = runtimeMethodInfo.CreateDelegateNoThrowOnBindFailure(runtimeDelegateTypeInfo, firstArgument, allowClosed); + if (result == null) + { + if (throwOnBindFailure) + throw new ArgumentException(SR.Arg_DlgtTargMeth); + return null; + } + return result; + } // V1 api: Creates closed delegates to instance methods only, relaxed signature checking disallowed. [RequiresUnreferencedCode("The target method might be removed")] - public abstract Delegate CreateDelegate(Type type, object target, string method, bool ignoreCase, bool throwOnBindFailure); + public static Delegate CreateDelegate(Type type, object target, string method, bool ignoreCase, bool throwOnBindFailure) + { + ArgumentNullException.ThrowIfNull(type); + ArgumentNullException.ThrowIfNull(target); + ArgumentNullException.ThrowIfNull(method); + + if (!(type is RuntimeType runtimeDelegateType)) + throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(type)); + + RuntimeTypeInfo runtimeDelegateTypeInfo = runtimeDelegateType.GetRuntimeTypeInfo(); + if (!runtimeDelegateTypeInfo.IsDelegate) + throw new ArgumentException(SR.Arg_MustBeDelegate); + + RuntimeTypeInfo runtimeContainingType = target.GetType().ToRuntimeTypeInfo(); + RuntimeMethodInfo runtimeMethodInfo = LookupMethodForCreateDelegate(runtimeDelegateTypeInfo, runtimeContainingType, method, isStatic: false, ignoreCase: ignoreCase); + if (runtimeMethodInfo == null) + { + if (throwOnBindFailure) + throw new ArgumentException(SR.Arg_DlgtTargMeth); + return null; + } + return runtimeMethodInfo.CreateDelegateWithoutSignatureValidation(type, target, isStatic: false, isOpen: false); + } // V1 api: Creates open delegates to static methods only, relaxed signature checking disallowed. - public abstract Delegate CreateDelegate(Type type, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.AllMethods)] Type target, string method, bool ignoreCase, bool throwOnBindFailure); + public static Delegate CreateDelegate(Type type, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.AllMethods)] Type target, string method, bool ignoreCase, bool throwOnBindFailure) + { + ArgumentNullException.ThrowIfNull(type); + ArgumentNullException.ThrowIfNull(target); + if (target.ContainsGenericParameters) + throw new ArgumentException(SR.Arg_UnboundGenParam, nameof(target)); + ArgumentNullException.ThrowIfNull(method); + + if (!(type is RuntimeType runtimeDelegateType)) + throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(type)); + + if (!(target is RuntimeType runtimeContainingType)) + throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(target)); + + RuntimeTypeInfo runtimeDelegateTypeInfo = runtimeDelegateType.GetRuntimeTypeInfo(); + + if (!runtimeDelegateTypeInfo.IsDelegate) + throw new ArgumentException(SR.Arg_MustBeDelegate); + + RuntimeMethodInfo runtimeMethodInfo = LookupMethodForCreateDelegate(runtimeDelegateTypeInfo, runtimeContainingType.GetRuntimeTypeInfo(), method, isStatic: true, ignoreCase: ignoreCase); + if (runtimeMethodInfo == null) + { + if (throwOnBindFailure) + throw new ArgumentException(SR.Arg_DlgtTargMeth); + return null; + } + return runtimeMethodInfo.CreateDelegateWithoutSignatureValidation(type, target: null, isStatic: true, isOpen: true); + } + + // + // Helper for the V1/V1.1 Delegate.CreateDelegate() api. These apis take method names rather than MethodInfo and only expect to create open static delegates + // or closed instance delegates. For backward compatibility, they don't allow relaxed signature matching (which could make the choice of target method ambiguous.) + // + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2075:UnrecognizedReflectionPattern", + Justification = "Analysis does not track annotations for RuntimeTypeInfo")] + private static RuntimeMethodInfo LookupMethodForCreateDelegate(RuntimeTypeInfo runtimeDelegateType, RuntimeTypeInfo containingType, string method, bool isStatic, bool ignoreCase) + { + Debug.Assert(runtimeDelegateType.IsDelegate); + + BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.ExactBinding; + if (isStatic) + { + bindingFlags |= BindingFlags.Static; + } + else + { + bindingFlags |= BindingFlags.Instance | BindingFlags.DeclaredOnly; + } + if (ignoreCase) + { + bindingFlags |= BindingFlags.IgnoreCase; + } + RuntimeMethodInfo invokeMethod = runtimeDelegateType.GetInvokeMethod(); + ReadOnlySpan parameters = invokeMethod.GetParametersAsSpan(); + int numParameters = parameters.Length; + Type[] parameterTypes = new Type[numParameters]; + for (int i = 0; i < numParameters; i++) + { + parameterTypes[i] = parameters[i].ParameterType; + } + + Type? type = containingType.ToType(); + while (type != null) + { + MethodInfo? methodInfo = type.GetMethod(method, 0, bindingFlags, parameterTypes); + if (methodInfo != null && methodInfo.ReturnType.Equals(invokeMethod.ReturnType)) + return (RuntimeMethodInfo)methodInfo; // This cast is safe since we already verified that containingType is runtime implemented. + + type = type.BaseType; + } + return null; + } + + public static IntPtr GetFunctionPointer(RuntimeMethodHandle runtimeMethodHandle, RuntimeTypeHandle declaringTypeHandle) + { + MethodBase method = GetMethodFromHandle(runtimeMethodHandle, declaringTypeHandle); + + switch (method) + { + case RuntimeMethodInfo methodInfo: + return methodInfo.LdFtnResult; + case RuntimeConstructorInfo constructorInfo: + return constructorInfo.LdFtnResult; + default: + Debug.Fail("RuntimeMethodHandle should only return a methodbase implemented by the runtime."); + throw new NotSupportedException(); + } + } + + public static void MakeTypedReference(object target, FieldInfo[] flds, out Type type, out int offset) + { + ArgumentNullException.ThrowIfNull(target); + ArgumentNullException.ThrowIfNull(flds); + if (flds.Length == 0) + throw new ArgumentException(SR.Arg_ArrayZeroError, nameof(flds)); + + offset = 0; + Type targetType = target.GetType(); + for (int i = 0; i < flds.Length; i++) + { + if (!(flds[i] is RuntimeFieldInfo field)) + throw new ArgumentException(SR.Argument_MustBeRuntimeFieldInfo); + if (field.IsStatic) + throw new ArgumentException(SR.Argument_TypedReferenceInvalidField); + + // For proper handling of Nullable don't change to something like 'IsAssignableFrom' + // Currently we can't make a TypedReference to fields of Nullable, which is fine. + Type declaringType = field.DeclaringType; + if (targetType != declaringType && !targetType.IsSubclassOf(declaringType)) + throw new MissingMemberException(SR.MissingMemberTypeRef); // MissingMemberException is a strange exception to throw, but it is the compatible exception. + + Type fieldType = field.FieldType; + if (i < (flds.Length - 1) && !fieldType.IsValueType) + throw new MissingMemberException(SR.MissingMemberNestErr); // MissingMemberException is a strange exception to throw, but it is the compatible exception. + + targetType = fieldType; + offset = checked(offset + field.Offset); + } + + type = targetType; + } + + public static Assembly[] GetLoadedAssemblies() => RuntimeAssemblyInfo.GetLoadedAssemblies(); - public abstract IntPtr GetFunctionPointer(RuntimeMethodHandle runtimeMethodHandle, RuntimeTypeHandle declaringTypeHandle); + public static EnumInfo GetEnumInfo(Type type, Func create) + { + RuntimeTypeInfo runtimeType = type.ToRuntimeTypeInfo(); - public abstract void MakeTypedReference(object target, FieldInfo[] flds, out Type type, out int offset); + var info = runtimeType.GenericCache as EnumInfo; + if (info != null) + return info; - public abstract Assembly[] GetLoadedAssemblies(); + ReflectionCoreExecution.ExecutionEnvironment.GetEnumInfo(runtimeType.TypeHandle, out string[] unsortedNames, out object[] unsortedValues, out bool isFlags); - public abstract EnumInfo GetEnumInfo(Type type, Func create); + // Call into IntrospectiveSort directly to avoid the Comparer.Default codepath. + // That codepath would bring functionality to compare everything that was ever allocated in the program. + ArraySortHelper.IntrospectiveSort(unsortedValues, unsortedNames, EnumUnderlyingTypeComparer.Instance); - public abstract DynamicInvokeInfo GetDelegateDynamicInvokeInfo(Type type); + info = create(RuntimeAugments.GetEnumUnderlyingType(type.TypeHandle), unsortedNames, unsortedValues, isFlags); - public abstract MethodInfo GetDelegateMethod(Delegate del); + runtimeType.GenericCache = info; + return info; + } - public abstract MethodBase GetMethodBaseFromStartAddressIfAvailable(IntPtr methodStartAddress); + private sealed class EnumUnderlyingTypeComparer : IComparer + { + public static readonly EnumUnderlyingTypeComparer Instance = new EnumUnderlyingTypeComparer(); + + public int Compare(object? x, object? y) + { + Debug.Assert(x is byte or ushort or uint or ulong); + return x switch + { + byte b => b.CompareTo((byte)y!), + ushort us => us.CompareTo((ushort)y!), + uint ui => ui.CompareTo((uint)y!), + _ => ((ulong)x!).CompareTo((ulong)y!), + }; + } + } + + public static DynamicInvokeInfo GetDelegateDynamicInvokeInfo(Type type) + { + RuntimeTypeInfo runtimeType = type.ToRuntimeTypeInfo(); - public abstract Assembly GetAssemblyForHandle(RuntimeTypeHandle typeHandle); + DynamicInvokeInfo? info = runtimeType.GenericCache as DynamicInvokeInfo; + if (info != null) + return info; - public abstract void RunClassConstructor(RuntimeTypeHandle typeHandle); + RuntimeMethodInfo invokeMethod = runtimeType.GetInvokeMethod(); + + MethodBaseInvoker methodInvoker = invokeMethod.MethodInvoker; + IntPtr invokeThunk = ReflectionCoreExecution.ExecutionEnvironment.GetDynamicInvokeThunk(methodInvoker); + + info = new DynamicInvokeInfo(invokeMethod, invokeThunk); + runtimeType.GenericCache = info; + return info; + } + + public static MethodInfo GetDelegateMethod(Delegate del) + { + return ReflectionCoreExecution.ExecutionEnvironment.GetDelegateMethod(del); + } + + public static MethodBase GetMethodBaseFromStartAddressIfAvailable(IntPtr methodStartAddress) + { + return ReflectionCoreExecution.ExecutionEnvironment.GetMethodBaseFromStartAddressIfAvailable(methodStartAddress); + } + + public static Assembly GetAssemblyForHandle(RuntimeTypeHandle typeHandle) + { + return Type.GetTypeFromHandle(typeHandle).Assembly; + } + + public static void RunClassConstructor(RuntimeTypeHandle typeHandle) + { + IntPtr pStaticClassConstructionContext = ReflectionCoreExecution.ExecutionEnvironment.GetStaticClassConstructionContext(typeHandle); + if (pStaticClassConstructionContext != IntPtr.Zero) + { + RuntimeAugments.EnsureClassConstructorRun(pStaticClassConstructionContext); + } + } } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Core/Execution/ReflectionCoreExecution.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Core/Execution/ReflectionCoreExecution.cs index 5825786d73645e..d3cd08985f340d 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Core/Execution/ReflectionCoreExecution.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Core/Execution/ReflectionCoreExecution.cs @@ -24,9 +24,6 @@ public static void InitializeExecutionDomain(ExecutionEnvironment executionEnvir { Debug.Assert(s_executionEnvironment == null); s_executionEnvironment = executionEnvironment; - - ReflectionCoreCallbacks reflectionCallbacks = new ReflectionCoreCallbacksImplementation(); - ReflectionAugments.Initialize(reflectionCallbacks); } internal static ExecutionEnvironment ExecutionEnvironment diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeInheritanceRules.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeInheritanceRules.cs index 804e445b7b79fd..f904fe769abeea 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeInheritanceRules.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeInheritanceRules.cs @@ -171,7 +171,7 @@ protected sealed override IEnumerable GetDeclaredCustomAttr public sealed override MethodInfo GetParent(MethodInfo e) { - return ReflectionAugments.ReflectionCoreCallbacks.GetImplicitlyOverriddenBaseClassMethod(e); + return ReflectionAugments.GetImplicitlyOverriddenBaseClassMethod(e); } public static readonly MethodCustomAttributeSearcher Default = new MethodCustomAttributeSearcher(); @@ -189,7 +189,7 @@ protected sealed override IEnumerable GetDeclaredCustomAttr public sealed override PropertyInfo GetParent(PropertyInfo e) { - return ReflectionAugments.ReflectionCoreCallbacks.GetImplicitlyOverriddenBaseClassProperty(e); + return ReflectionAugments.GetImplicitlyOverriddenBaseClassProperty(e); } public static readonly PropertyCustomAttributeSearcher Default = new PropertyCustomAttributeSearcher(); @@ -208,7 +208,7 @@ protected sealed override IEnumerable GetDeclaredCustomAttr public sealed override EventInfo GetParent(EventInfo e) { - return ReflectionAugments.ReflectionCoreCallbacks.GetImplicitlyOverriddenBaseClassEvent(e); + return ReflectionAugments.GetImplicitlyOverriddenBaseClassEvent(e); } public static readonly EventCustomAttributeSearcher Default = new EventCustomAttributeSearcher(); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs index 6b246e4ee4567e..8fa7c789fd0afa 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs @@ -299,7 +299,7 @@ internal static unsafe void FixupModuleCell(ModuleFixupCell* pCell) dllImportSearchPath = pCell->DllImportSearchPathAndCookie & ~InteropDataConstants.HasDllImportSearchPath; } - Assembly callingAssembly = ReflectionAugments.ReflectionCoreCallbacks.GetAssemblyForHandle(new RuntimeTypeHandle(pCell->CallingAssemblyType)); + Assembly callingAssembly = ReflectionAugments.GetAssemblyForHandle(new RuntimeTypeHandle(pCell->CallingAssemblyType)); // First check if there's a NativeLibrary callback and call it to attempt the resolution IntPtr hModule = NativeLibrary.LoadLibraryCallbackStub(moduleName, callingAssembly, hasDllImportSearchPath, dllImportSearchPath); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/ReflectionHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/ReflectionHelpers.cs index dbdc93b93bac7e..326ba35ae0e434 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/ReflectionHelpers.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/ReflectionHelpers.cs @@ -30,7 +30,7 @@ public static Type ExtensibleGetType(string typeName, string callingAssemblyName // This supports Assembly.GetExecutingAssembly() intrinsic expansion in the compiler public static Assembly GetExecutingAssembly(RuntimeTypeHandle typeHandle) { - return ReflectionAugments.ReflectionCoreCallbacks.GetAssemblyForHandle(typeHandle); + return ReflectionAugments.GetAssemblyForHandle(typeHandle); } // This supports MethodBase.GetCurrentMethod() intrinsic expansion in the compiler diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj index ead6f8350b2773..a37ba28ad85f15 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj @@ -425,7 +425,6 @@ - diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Activator.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Activator.NativeAot.cs index ab710ed580453f..2fd232d4ad9e92 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Activator.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Activator.NativeAot.cs @@ -109,12 +109,12 @@ private struct StructWithNoConstructor { public StructWithNoConstructor() { } } [DebuggerHidden] [DebuggerStepThrough] public static object? CreateInstance([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type type, bool nonPublic) - => ReflectionAugments.ReflectionCoreCallbacks.ActivatorCreateInstance(type, nonPublic); + => ReflectionAugments.ActivatorCreateInstance(type, nonPublic); [DebuggerHidden] [DebuggerStepThrough] public static object? CreateInstance([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicConstructors)] Type type, BindingFlags bindingAttr, Binder? binder, object?[]? args, CultureInfo? culture, object?[]? activationAttributes) - => ReflectionAugments.ReflectionCoreCallbacks.ActivatorCreateInstance(type, bindingAttr, binder, args, culture, activationAttributes); + => ReflectionAugments.ActivatorCreateInstance(type, bindingAttr, binder, args, culture, activationAttributes); [RequiresUnreferencedCode("Type and its constructor could be removed")] public static ObjectHandle CreateInstance(string assemblyName, string typeName) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Delegate.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Delegate.cs index 49e0c7c9c707de..2ad2166546121a 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Delegate.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Delegate.cs @@ -244,7 +244,7 @@ private IntPtr GetActualTargetFunctionPointer(object thisObject) } else { - DynamicInvokeInfo dynamicInvokeInfo = ReflectionAugments.ReflectionCoreCallbacks.GetDelegateDynamicInvokeInfo(GetType()); + DynamicInvokeInfo dynamicInvokeInfo = ReflectionAugments.GetDelegateDynamicInvokeInfo(GetType()); object? result = dynamicInvokeInfo.Invoke(_firstParameter, _functionPointer, args, binderBundle: null, wrapInTargetInvocationException: true); @@ -270,7 +270,7 @@ protected virtual MethodInfo GetMethodImpl() return GetType().GetMethod("Invoke"); } - return ReflectionAugments.ReflectionCoreCallbacks.GetDelegateMethod(this); + return ReflectionAugments.GetDelegateMethod(this); } internal DiagnosticMethodInfo GetDiagnosticMethodInfo() @@ -294,7 +294,7 @@ internal DiagnosticMethodInfo GetDiagnosticMethodInfo() IntPtr ldftnResult = GetDelegateLdFtnResult(out RuntimeTypeHandle _, out bool isOpenResolver); if (isOpenResolver) { - MethodInfo mi = ReflectionAugments.ReflectionCoreCallbacks.GetDelegateMethod(this); + MethodInfo mi = ReflectionAugments.GetDelegateMethod(this); Type? declaringType = mi.DeclaringType; if (declaringType.IsConstructedGenericType) declaringType = declaringType.GetGenericTypeDefinition(); @@ -354,17 +354,17 @@ public object? Target } // V2 api: Creates open or closed delegates to static or instance methods - relaxed signature checking allowed. - public static Delegate CreateDelegate(Type type, object? firstArgument, MethodInfo method, bool throwOnBindFailure) => ReflectionAugments.ReflectionCoreCallbacks.CreateDelegate(type, firstArgument, method, throwOnBindFailure); + public static Delegate CreateDelegate(Type type, object? firstArgument, MethodInfo method, bool throwOnBindFailure) => ReflectionAugments.CreateDelegate(type, firstArgument, method, throwOnBindFailure); // V1 api: Creates open delegates to static or instance methods - relaxed signature checking allowed. - public static Delegate CreateDelegate(Type type, MethodInfo method, bool throwOnBindFailure) => ReflectionAugments.ReflectionCoreCallbacks.CreateDelegate(type, method, throwOnBindFailure); + public static Delegate CreateDelegate(Type type, MethodInfo method, bool throwOnBindFailure) => ReflectionAugments.CreateDelegate(type, method, throwOnBindFailure); // V1 api: Creates closed delegates to instance methods only, relaxed signature checking disallowed. [RequiresUnreferencedCode("The target method might be removed")] - public static Delegate CreateDelegate(Type type, object target, string method, bool ignoreCase, bool throwOnBindFailure) => ReflectionAugments.ReflectionCoreCallbacks.CreateDelegate(type, target, method, ignoreCase, throwOnBindFailure); + public static Delegate CreateDelegate(Type type, object target, string method, bool ignoreCase, bool throwOnBindFailure) => ReflectionAugments.CreateDelegate(type, target, method, ignoreCase, throwOnBindFailure); // V1 api: Creates open delegates to static methods only, relaxed signature checking disallowed. - public static Delegate CreateDelegate(Type type, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.AllMethods)] Type target, string method, bool ignoreCase, bool throwOnBindFailure) => ReflectionAugments.ReflectionCoreCallbacks.CreateDelegate(type, target, method, ignoreCase, throwOnBindFailure); + public static Delegate CreateDelegate(Type type, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.AllMethods)] Type target, string method, bool ignoreCase, bool throwOnBindFailure) => ReflectionAugments.CreateDelegate(type, target, method, ignoreCase, throwOnBindFailure); internal IntPtr TryGetOpenStaticFunctionPointer() => (GetThunk(OpenStaticThunk) == _functionPointer) ? _extraFunctionPointerOrData : 0; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Diagnostics/StackFrame.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Diagnostics/StackFrame.NativeAot.cs index f4b862c171778a..29463a5f79aab0 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Diagnostics/StackFrame.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Diagnostics/StackFrame.NativeAot.cs @@ -69,7 +69,7 @@ private bool TryInitializeMethodBase() IntPtr methodStartAddress = _ipAddress - _nativeOffset; Debug.Assert(RuntimeImports.RhFindMethodStartAddress(_ipAddress) == methodStartAddress); - _method = ReflectionAugments.ReflectionCoreCallbacks.GetMethodBaseFromStartAddressIfAvailable(methodStartAddress); + _method = ReflectionAugments.GetMethodBaseFromStartAddressIfAvailable(methodStartAddress); if (_method == null) { _noMethodBaseAvailable = true; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Enum.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Enum.NativeAot.cs index d9914ad15367f9..0b8fd582e56e65 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Enum.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Enum.NativeAot.cs @@ -48,7 +48,7 @@ internal static EnumInfo GetEnumInfo(RuntimeType enumType, b typeof(TStorage) == typeof(uint) || typeof(TStorage) == typeof(ulong)); - return (EnumInfo)ReflectionAugments.ReflectionCoreCallbacks.GetEnumInfo(enumType, + return (EnumInfo)ReflectionAugments.GetEnumInfo(enumType, static (underlyingType, names, valuesAsObject, isFlags) => { // Only after we've sorted, create the underlying array. diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Assembly.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Assembly.NativeAot.cs index 019e8d8d688b00..2e0ba72727f33d 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Assembly.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Assembly.NativeAot.cs @@ -24,7 +24,7 @@ public static Assembly GetCallingAssembly() throw new PlatformNotSupportedException(); } - public static Assembly Load(AssemblyName assemblyRef) => ReflectionAugments.ReflectionCoreCallbacks.Load(assemblyRef, throwOnFileNotFound: true); + public static Assembly Load(AssemblyName assemblyRef) => ReflectionAugments.Load(assemblyRef, throwOnFileNotFound: true); public static Assembly Load(string assemblyString) { diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/FieldInfo.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/FieldInfo.NativeAot.cs index 4eacd387bbb7cf..aab512dbf408da 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/FieldInfo.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/FieldInfo.NativeAot.cs @@ -7,7 +7,7 @@ namespace System.Reflection { public abstract partial class FieldInfo : MemberInfo { - public static FieldInfo GetFieldFromHandle(RuntimeFieldHandle handle) => ReflectionAugments.ReflectionCoreCallbacks.GetFieldFromHandle(handle); - public static FieldInfo GetFieldFromHandle(RuntimeFieldHandle handle, RuntimeTypeHandle declaringType) => ReflectionAugments.ReflectionCoreCallbacks.GetFieldFromHandle(handle, declaringType); + public static FieldInfo GetFieldFromHandle(RuntimeFieldHandle handle) => ReflectionAugments.GetFieldFromHandle(handle); + public static FieldInfo GetFieldFromHandle(RuntimeFieldHandle handle, RuntimeTypeHandle declaringType) => ReflectionAugments.GetFieldFromHandle(handle, declaringType); } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/MethodBase.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/MethodBase.NativeAot.cs index e4bd020d0604a6..509d5a4986b061 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/MethodBase.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/MethodBase.NativeAot.cs @@ -9,8 +9,8 @@ namespace System.Reflection { public abstract partial class MethodBase : MemberInfo { - public static MethodBase GetMethodFromHandle(RuntimeMethodHandle handle) => ReflectionAugments.ReflectionCoreCallbacks.GetMethodFromHandle(handle); - public static MethodBase GetMethodFromHandle(RuntimeMethodHandle handle, RuntimeTypeHandle declaringType) => ReflectionAugments.ReflectionCoreCallbacks.GetMethodFromHandle(handle, declaringType); + public static MethodBase GetMethodFromHandle(RuntimeMethodHandle handle) => ReflectionAugments.GetMethodFromHandle(handle); + public static MethodBase GetMethodFromHandle(RuntimeMethodHandle handle, RuntimeTypeHandle declaringType) => ReflectionAugments.GetMethodFromHandle(handle, declaringType); [RequiresUnreferencedCode("Metadata for the method might be incomplete or removed")] [System.Runtime.CompilerServices.Intrinsic] diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/ReflectionCoreCallbacksImplementation.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/ReflectionCoreCallbacksImplementation.cs deleted file mode 100644 index cacebc5f9d87fc..00000000000000 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/ReflectionCoreCallbacksImplementation.cs +++ /dev/null @@ -1,466 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; -using System.Reflection.Runtime.Assemblies; -using System.Reflection.Runtime.BindingFlagSupport; -using System.Reflection.Runtime.FieldInfos; -using System.Reflection.Runtime.FieldInfos.NativeFormat; -using System.Reflection.Runtime.General; -using System.Reflection.Runtime.MethodInfos; -using System.Reflection.Runtime.Modules; -using System.Reflection.Runtime.TypeInfos; -using System.Reflection.Runtime.TypeInfos.NativeFormat; -using System.Runtime.CompilerServices; - -using Internal.Metadata.NativeFormat; -using Internal.Reflection.Augments; -using Internal.Reflection.Core.Execution; -using Internal.Runtime.Augments; - -namespace System.Reflection.Runtime.General -{ - internal sealed class ReflectionCoreCallbacksImplementation : ReflectionCoreCallbacks - { - internal ReflectionCoreCallbacksImplementation() - { - } - - public sealed override Assembly Load(AssemblyName assemblyRef, bool throwOnFileNotFound) - { - ArgumentNullException.ThrowIfNull(assemblyRef); - - if (throwOnFileNotFound) - return RuntimeAssemblyInfo.GetRuntimeAssembly(assemblyRef.ToRuntimeAssemblyName()); - else - return RuntimeAssemblyInfo.GetRuntimeAssemblyIfExists(assemblyRef.ToRuntimeAssemblyName()); - } - - public sealed override Assembly Load(ReadOnlySpan rawAssembly, ReadOnlySpan pdbSymbolStore) - { - if (rawAssembly.IsEmpty) - throw new ArgumentNullException(nameof(rawAssembly)); - - return RuntimeAssemblyInfo.GetRuntimeAssemblyFromByteArray(rawAssembly, pdbSymbolStore); - } - - public sealed override Assembly Load(string assemblyPath) - { - ArgumentNullException.ThrowIfNull(assemblyPath); - - return RuntimeAssemblyInfo.GetRuntimeAssemblyFromPath(assemblyPath); - } - - // - // This overload of GetMethodForHandle only accepts handles for methods declared on non-generic types (the method, however, - // can be an instance of a generic method.) To resolve handles for methods declared on generic types, you must pass - // the declaring type explicitly using the two-argument overload of GetMethodFromHandle. - // - // This is a vestige from desktop generic sharing that got itself enshrined in the code generated by the C# compiler for Linq Expressions. - // - public sealed override MethodBase GetMethodFromHandle(RuntimeMethodHandle runtimeMethodHandle) - { - ExecutionEnvironment executionEnvironment = ReflectionCoreExecution.ExecutionEnvironment; - QMethodDefinition methodHandle; - RuntimeTypeHandle declaringTypeHandle; - RuntimeTypeHandle[] genericMethodTypeArgumentHandles; - if (!executionEnvironment.TryGetMethodFromHandle(runtimeMethodHandle, out declaringTypeHandle, out methodHandle, out genericMethodTypeArgumentHandles)) - throw new ArgumentException(SR.Argument_InvalidHandle); - - MethodBase methodBase = ExecutionDomain.GetMethod(declaringTypeHandle, methodHandle, genericMethodTypeArgumentHandles); - if (methodBase.DeclaringType.IsConstructedGenericType) // For compat with desktop, insist that the caller pass us the declaring type to resolve members of generic types. - throw new ArgumentException(SR.Format(SR.Argument_MethodDeclaringTypeGeneric, methodBase)); - return methodBase; - } - - // - // This overload of GetMethodHandle can handle all method handles. - // - public sealed override MethodBase GetMethodFromHandle(RuntimeMethodHandle runtimeMethodHandle, RuntimeTypeHandle declaringTypeHandle) - { - ExecutionEnvironment executionEnvironment = ReflectionCoreExecution.ExecutionEnvironment; - QMethodDefinition methodHandle; - RuntimeTypeHandle[] genericMethodTypeArgumentHandles; - if (!executionEnvironment.TryGetMethodFromHandleAndType(runtimeMethodHandle, declaringTypeHandle, out methodHandle, out genericMethodTypeArgumentHandles)) - { - // This may be a method declared on a non-generic type: this api accepts that too so try the other table. - RuntimeTypeHandle actualDeclaringTypeHandle; - if (!executionEnvironment.TryGetMethodFromHandle(runtimeMethodHandle, out actualDeclaringTypeHandle, out methodHandle, out genericMethodTypeArgumentHandles)) - throw new ArgumentException(SR.Argument_InvalidHandle); - if (!actualDeclaringTypeHandle.Equals(declaringTypeHandle)) - throw new ArgumentException(SR.Format(SR.Argument_ResolveMethodHandle, - declaringTypeHandle.GetRuntimeTypeInfoForRuntimeTypeHandle(), - actualDeclaringTypeHandle.GetRuntimeTypeInfoForRuntimeTypeHandle())); - } - - MethodBase methodBase = ExecutionDomain.GetMethod(declaringTypeHandle, methodHandle, genericMethodTypeArgumentHandles); - return methodBase; - } - - // - // This overload of GetFieldForHandle only accepts handles for fields declared on non-generic types. To resolve handles for fields - // declared on generic types, you must pass the declaring type explicitly using the two-argument overload of GetFieldFromHandle. - // - // This is a vestige from desktop generic sharing that got itself enshrined in the code generated by the C# compiler for Linq Expressions. - // - public sealed override FieldInfo GetFieldFromHandle(RuntimeFieldHandle runtimeFieldHandle) - { - ExecutionEnvironment executionEnvironment = ReflectionCoreExecution.ExecutionEnvironment; - FieldHandle fieldHandle; - RuntimeTypeHandle declaringTypeHandle; - if (!executionEnvironment.TryGetFieldFromHandle(runtimeFieldHandle, out declaringTypeHandle, out fieldHandle)) - throw new ArgumentException(SR.Argument_InvalidHandle); - - FieldInfo fieldInfo = GetFieldInfo(declaringTypeHandle, fieldHandle); - if (fieldInfo.DeclaringType.IsConstructedGenericType) // For compat with desktop, insist that the caller pass us the declaring type to resolve members of generic types. - throw new ArgumentException(SR.Format(SR.Argument_FieldDeclaringTypeGeneric, fieldInfo)); - return fieldInfo; - } - - // - // This overload of GetFieldHandle can handle all field handles. - // - public sealed override FieldInfo GetFieldFromHandle(RuntimeFieldHandle runtimeFieldHandle, RuntimeTypeHandle declaringTypeHandle) - { - ExecutionEnvironment executionEnvironment = ReflectionCoreExecution.ExecutionEnvironment; - FieldHandle fieldHandle; - if (!executionEnvironment.TryGetFieldFromHandleAndType(runtimeFieldHandle, declaringTypeHandle, out fieldHandle)) - { - // This may be a field declared on a non-generic type: this api accepts that too so try the other table. - RuntimeTypeHandle actualDeclaringTypeHandle; - if (!executionEnvironment.TryGetFieldFromHandle(runtimeFieldHandle, out actualDeclaringTypeHandle, out fieldHandle)) - throw new ArgumentException(SR.Argument_InvalidHandle); - if (!actualDeclaringTypeHandle.Equals(declaringTypeHandle)) - throw new ArgumentException(SR.Format(SR.Argument_ResolveFieldHandle, - declaringTypeHandle.GetRuntimeTypeInfoForRuntimeTypeHandle(), - actualDeclaringTypeHandle.GetRuntimeTypeInfoForRuntimeTypeHandle())); - } - - FieldInfo fieldInfo = GetFieldInfo(declaringTypeHandle, fieldHandle); - return fieldInfo; - } - - public sealed override EventInfo GetImplicitlyOverriddenBaseClassEvent(EventInfo e) - { - return e.GetImplicitlyOverriddenBaseClassMember(EventPolicies.Instance); - } - - public sealed override MethodInfo GetImplicitlyOverriddenBaseClassMethod(MethodInfo m) - { - return m.GetImplicitlyOverriddenBaseClassMember(MethodPolicies.Instance); - } - - public sealed override PropertyInfo GetImplicitlyOverriddenBaseClassProperty(PropertyInfo p) - { - return p.GetImplicitlyOverriddenBaseClassMember(PropertyPolicies.Instance); - } - - private static RuntimeFieldInfo GetFieldInfo(RuntimeTypeHandle declaringTypeHandle, FieldHandle fieldHandle) - { - RuntimeTypeInfo contextTypeInfo = declaringTypeHandle.GetRuntimeTypeInfoForRuntimeTypeHandle(); - NativeFormatRuntimeNamedTypeInfo definingTypeInfo = contextTypeInfo.AnchoringTypeDefinitionForDeclaredMembers.CastToNativeFormatRuntimeNamedTypeInfo(); - - // RuntimeFieldHandles always yield FieldInfo's whose ReflectedType equals the DeclaringType. - RuntimeTypeInfo reflectedType = contextTypeInfo; - return NativeFormatRuntimeFieldInfo.GetRuntimeFieldInfo(fieldHandle, definingTypeInfo, contextTypeInfo, reflectedType); - } - - [DebuggerHidden] - [DebuggerStepThrough] - public sealed override object ActivatorCreateInstance( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] - Type type, bool nonPublic) - { - return ActivatorImplementation.CreateInstance(type, nonPublic); - } - - [DebuggerHidden] - [DebuggerStepThrough] - public sealed override object ActivatorCreateInstance( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] - Type type, BindingFlags bindingAttr, Binder? binder, object?[]? args, CultureInfo? culture, object?[]? activationAttributes) - { - return ActivatorImplementation.CreateInstance(type, bindingAttr, binder, args, culture, activationAttributes); - } - - // V2 api: Creates open or closed delegates to static or instance methods - relaxed signature checking allowed. - public sealed override Delegate CreateDelegate(Type type, object firstArgument, MethodInfo method, bool throwOnBindFailure) - { - return CreateDelegateWorker(type, firstArgument, method, throwOnBindFailure, allowClosed: true); - } - - // V1 api: Creates open delegates to static or instance methods - relaxed signature checking allowed. - public sealed override Delegate CreateDelegate(Type type, MethodInfo method, bool throwOnBindFailure) - { - // This API existed in v1/v1.1 and only expected to create open - // instance delegates, so we forbid closed delegates for backward compatibility. - // But we'll allow relaxed signature checking and open static delegates because - // there's no ambiguity there (the caller would have to explicitly - // pass us a static method or a method with a non-exact signature - // and the only change in behavior from v1.1 there is that we won't - // fail the call). - return CreateDelegateWorker(type, null, method, throwOnBindFailure, allowClosed: false); - } - - private static Delegate CreateDelegateWorker(Type type, object firstArgument, MethodInfo method, bool throwOnBindFailure, bool allowClosed) - { - ArgumentNullException.ThrowIfNull(type); - ArgumentNullException.ThrowIfNull(method); - - if (!(type is RuntimeType runtimeDelegateType)) - throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(type)); - - if (!(method is RuntimeMethodInfo runtimeMethodInfo)) - throw new ArgumentException(SR.Argument_MustBeRuntimeMethodInfo, nameof(method)); - - RuntimeTypeInfo runtimeDelegateTypeInfo = runtimeDelegateType.GetRuntimeTypeInfo(); - - if (!runtimeDelegateTypeInfo.IsDelegate) - throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(type)); - - Delegate result = runtimeMethodInfo.CreateDelegateNoThrowOnBindFailure(runtimeDelegateTypeInfo, firstArgument, allowClosed); - if (result == null) - { - if (throwOnBindFailure) - throw new ArgumentException(SR.Arg_DlgtTargMeth); - return null; - } - return result; - } - - // V1 api: Creates closed delegates to instance methods only, relaxed signature checking disallowed. - [RequiresUnreferencedCode("The target method might be removed")] - public sealed override Delegate CreateDelegate(Type type, object target, string method, bool ignoreCase, bool throwOnBindFailure) - { - ArgumentNullException.ThrowIfNull(type); - ArgumentNullException.ThrowIfNull(target); - ArgumentNullException.ThrowIfNull(method); - - if (!(type is RuntimeType runtimeDelegateType)) - throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(type)); - - RuntimeTypeInfo runtimeDelegateTypeInfo = runtimeDelegateType.GetRuntimeTypeInfo(); - if (!runtimeDelegateTypeInfo.IsDelegate) - throw new ArgumentException(SR.Arg_MustBeDelegate); - - RuntimeTypeInfo runtimeContainingType = target.GetType().ToRuntimeTypeInfo(); - RuntimeMethodInfo runtimeMethodInfo = LookupMethodForCreateDelegate(runtimeDelegateTypeInfo, runtimeContainingType, method, isStatic: false, ignoreCase: ignoreCase); - if (runtimeMethodInfo == null) - { - if (throwOnBindFailure) - throw new ArgumentException(SR.Arg_DlgtTargMeth); - return null; - } - return runtimeMethodInfo.CreateDelegateWithoutSignatureValidation(type, target, isStatic: false, isOpen: false); - } - - // V1 api: Creates open delegates to static methods only, relaxed signature checking disallowed. - public sealed override Delegate CreateDelegate(Type type, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.AllMethods)] Type target, string method, bool ignoreCase, bool throwOnBindFailure) - { - ArgumentNullException.ThrowIfNull(type); - ArgumentNullException.ThrowIfNull(target); - if (target.ContainsGenericParameters) - throw new ArgumentException(SR.Arg_UnboundGenParam, nameof(target)); - ArgumentNullException.ThrowIfNull(method); - - if (!(type is RuntimeType runtimeDelegateType)) - throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(type)); - - if (!(target is RuntimeType runtimeContainingType)) - throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(target)); - - RuntimeTypeInfo runtimeDelegateTypeInfo = runtimeDelegateType.GetRuntimeTypeInfo(); - - if (!runtimeDelegateTypeInfo.IsDelegate) - throw new ArgumentException(SR.Arg_MustBeDelegate); - - RuntimeMethodInfo runtimeMethodInfo = LookupMethodForCreateDelegate(runtimeDelegateTypeInfo, runtimeContainingType.GetRuntimeTypeInfo(), method, isStatic: true, ignoreCase: ignoreCase); - if (runtimeMethodInfo == null) - { - if (throwOnBindFailure) - throw new ArgumentException(SR.Arg_DlgtTargMeth); - return null; - } - return runtimeMethodInfo.CreateDelegateWithoutSignatureValidation(type, target: null, isStatic: true, isOpen: true); - } - - // - // Helper for the V1/V1.1 Delegate.CreateDelegate() api. These apis take method names rather than MethodInfo and only expect to create open static delegates - // or closed instance delegates. For backward compatibility, they don't allow relaxed signature matching (which could make the choice of target method ambiguous.) - // - [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2075:UnrecognizedReflectionPattern", - Justification = "Analysis does not track annotations for RuntimeTypeInfo")] - private static RuntimeMethodInfo LookupMethodForCreateDelegate(RuntimeTypeInfo runtimeDelegateType, RuntimeTypeInfo containingType, string method, bool isStatic, bool ignoreCase) - { - Debug.Assert(runtimeDelegateType.IsDelegate); - - BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.ExactBinding; - if (isStatic) - { - bindingFlags |= BindingFlags.Static; - } - else - { - bindingFlags |= BindingFlags.Instance | BindingFlags.DeclaredOnly; - } - if (ignoreCase) - { - bindingFlags |= BindingFlags.IgnoreCase; - } - RuntimeMethodInfo invokeMethod = runtimeDelegateType.GetInvokeMethod(); - ReadOnlySpan parameters = invokeMethod.GetParametersAsSpan(); - int numParameters = parameters.Length; - Type[] parameterTypes = new Type[numParameters]; - for (int i = 0; i < numParameters; i++) - { - parameterTypes[i] = parameters[i].ParameterType; - } - - Type? type = containingType.ToType(); - while (type != null) - { - MethodInfo? methodInfo = type.GetMethod(method, 0, bindingFlags, parameterTypes); - if (methodInfo != null && methodInfo.ReturnType.Equals(invokeMethod.ReturnType)) - return (RuntimeMethodInfo)methodInfo; // This cast is safe since we already verified that containingType is runtime implemented. - - type = type.BaseType; - } - return null; - } - - public sealed override IntPtr GetFunctionPointer(RuntimeMethodHandle runtimeMethodHandle, RuntimeTypeHandle declaringTypeHandle) - { - MethodBase method = GetMethodFromHandle(runtimeMethodHandle, declaringTypeHandle); - - switch (method) - { - case RuntimeMethodInfo methodInfo: - return methodInfo.LdFtnResult; - case RuntimeConstructorInfo constructorInfo: - return constructorInfo.LdFtnResult; - default: - Debug.Fail("RuntimeMethodHandle should only return a methodbase implemented by the runtime."); - throw new NotSupportedException(); - } - } - - public sealed override void MakeTypedReference(object target, FieldInfo[] flds, out Type type, out int offset) - { - ArgumentNullException.ThrowIfNull(target); - ArgumentNullException.ThrowIfNull(flds); - if (flds.Length == 0) - throw new ArgumentException(SR.Arg_ArrayZeroError, nameof(flds)); - - offset = 0; - Type targetType = target.GetType(); - for (int i = 0; i < flds.Length; i++) - { - if (!(flds[i] is RuntimeFieldInfo field)) - throw new ArgumentException(SR.Argument_MustBeRuntimeFieldInfo); - if (field.IsStatic) - throw new ArgumentException(SR.Argument_TypedReferenceInvalidField); - - // For proper handling of Nullable don't change to something like 'IsAssignableFrom' - // Currently we can't make a TypedReference to fields of Nullable, which is fine. - Type declaringType = field.DeclaringType; - if (targetType != declaringType && !targetType.IsSubclassOf(declaringType)) - throw new MissingMemberException(SR.MissingMemberTypeRef); // MissingMemberException is a strange exception to throw, but it is the compatible exception. - - Type fieldType = field.FieldType; - if (i < (flds.Length - 1) && !fieldType.IsValueType) - throw new MissingMemberException(SR.MissingMemberNestErr); // MissingMemberException is a strange exception to throw, but it is the compatible exception. - - targetType = fieldType; - offset = checked(offset + field.Offset); - } - - type = targetType; - } - - public sealed override Assembly[] GetLoadedAssemblies() => RuntimeAssemblyInfo.GetLoadedAssemblies(); - - public sealed override EnumInfo GetEnumInfo(Type type, Func create) - { - RuntimeTypeInfo runtimeType = type.ToRuntimeTypeInfo(); - - var info = runtimeType.GenericCache as EnumInfo; - if (info != null) - return info; - - ReflectionCoreExecution.ExecutionEnvironment.GetEnumInfo(runtimeType.TypeHandle, out string[] unsortedNames, out object[] unsortedValues, out bool isFlags); - - // Call into IntrospectiveSort directly to avoid the Comparer.Default codepath. - // That codepath would bring functionality to compare everything that was ever allocated in the program. - ArraySortHelper.IntrospectiveSort(unsortedValues, unsortedNames, EnumUnderlyingTypeComparer.Instance); - - info = create(RuntimeAugments.GetEnumUnderlyingType(type.TypeHandle), unsortedNames, unsortedValues, isFlags); - - runtimeType.GenericCache = info; - return info; - } - - private sealed class EnumUnderlyingTypeComparer : IComparer - { - public static readonly EnumUnderlyingTypeComparer Instance = new EnumUnderlyingTypeComparer(); - - public int Compare(object? x, object? y) - { - Debug.Assert(x is byte or ushort or uint or ulong); - return x switch - { - byte b => b.CompareTo((byte)y!), - ushort us => us.CompareTo((ushort)y!), - uint ui => ui.CompareTo((uint)y!), - _ => ((ulong)x!).CompareTo((ulong)y!), - }; - } - } - - public sealed override DynamicInvokeInfo GetDelegateDynamicInvokeInfo(Type type) - { - RuntimeTypeInfo runtimeType = type.ToRuntimeTypeInfo(); - - DynamicInvokeInfo? info = runtimeType.GenericCache as DynamicInvokeInfo; - if (info != null) - return info; - - RuntimeMethodInfo invokeMethod = runtimeType.GetInvokeMethod(); - - MethodBaseInvoker methodInvoker = invokeMethod.MethodInvoker; - IntPtr invokeThunk = ReflectionCoreExecution.ExecutionEnvironment.GetDynamicInvokeThunk(methodInvoker); - - info = new DynamicInvokeInfo(invokeMethod, invokeThunk); - runtimeType.GenericCache = info; - return info; - } - - public sealed override MethodInfo GetDelegateMethod(Delegate del) - { - return ReflectionCoreExecution.ExecutionEnvironment.GetDelegateMethod(del); - } - - public sealed override MethodBase GetMethodBaseFromStartAddressIfAvailable(IntPtr methodStartAddress) - { - return ReflectionCoreExecution.ExecutionEnvironment.GetMethodBaseFromStartAddressIfAvailable(methodStartAddress); - } - - public sealed override Assembly GetAssemblyForHandle(RuntimeTypeHandle typeHandle) - { - return Type.GetTypeFromHandle(typeHandle).Assembly; - } - - public sealed override void RunClassConstructor(RuntimeTypeHandle typeHandle) - { - IntPtr pStaticClassConstructionContext = ReflectionCoreExecution.ExecutionEnvironment.GetStaticClassConstructionContext(typeHandle); - if (pStaticClassConstructionContext != IntPtr.Zero) - { - RuntimeAugments.EnsureClassConstructorRun(pStaticClassConstructionContext); - } - } - } -} diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs index 9587d6f2d67fea..834d6d2e60443c 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs @@ -21,7 +21,7 @@ public abstract class RuntimeAssembly : Assembly an.Flags = mainAssemblyAn.Flags; an.Version = version ?? mainAssemblyAn.Version; - Assembly? retAssembly = ReflectionAugments.ReflectionCoreCallbacks.Load(an, throwOnFileNotFound); + Assembly? retAssembly = ReflectionAugments.Load(an, throwOnFileNotFound); if (retAssembly == mainAssembly) { diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs index 2981b35f520734..8488a99f12a26f 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs @@ -45,7 +45,7 @@ public static void RunClassConstructor(RuntimeTypeHandle type) if (type.IsNull) throw new ArgumentException(SR.InvalidOperation_HandleIsNotInitialized); - ReflectionAugments.ReflectionCoreCallbacks.RunClassConstructor(type); + ReflectionAugments.RunClassConstructor(type); } public static void RunModuleConstructor(ModuleHandle module) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.NativeAot.cs index 1a854be55a5ede..bd40eed1212bdb 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.NativeAot.cs @@ -11,7 +11,7 @@ namespace System.Runtime.Loader { public partial class AssemblyLoadContext { - internal static Assembly[] GetLoadedAssemblies() => ReflectionAugments.ReflectionCoreCallbacks.GetLoadedAssemblies(); + internal static Assembly[] GetLoadedAssemblies() => ReflectionAugments.GetLoadedAssemblies(); public Assembly LoadFromAssemblyName(AssemblyName assemblyName) { @@ -45,14 +45,14 @@ private static Assembly InternalLoadFromPath(string? assemblyPath, string? nativ { // TODO: This is not passing down the AssemblyLoadContext, // so it won't actually work properly when multiple assemblies with the same identity get loaded. - return ReflectionAugments.ReflectionCoreCallbacks.Load(assemblyPath); + return ReflectionAugments.Load(assemblyPath); } #pragma warning restore IDE0060 #pragma warning disable CA1822 internal Assembly InternalLoad(ReadOnlySpan arrAssembly, ReadOnlySpan arrSymbols) { - return ReflectionAugments.ReflectionCoreCallbacks.Load(arrAssembly, arrSymbols); + return ReflectionAugments.Load(arrAssembly, arrSymbols); } #pragma warning restore CA1822 diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeExceptionHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeExceptionHelpers.cs index 0b994f72e8834b..6aebb6967cf21f 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeExceptionHelpers.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeExceptionHelpers.cs @@ -7,6 +7,7 @@ using System.Threading; using Internal.Reflection.Augments; +using Internal.Reflection.Core.Execution; namespace System { @@ -328,7 +329,7 @@ public static bool SafeToPerformRichExceptionSupport get { // Reflection needs to work as the exception code calls GetType() and GetType().ToString() - return ReflectionAugments.IsInitialized; + return ReflectionCoreExecution.ExecutionEnvironment != null; } } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeMethodHandle.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeMethodHandle.cs index b79874529f6512..3de517db8f37c1 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeMethodHandle.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeMethodHandle.cs @@ -109,7 +109,7 @@ public IntPtr GetFunctionPointer() RuntimeTypeHandle declaringType; RuntimeAugments.TypeLoaderCallbacks.GetRuntimeMethodHandleComponents(this, out declaringType, out _, out _); - return ReflectionAugments.ReflectionCoreCallbacks.GetFunctionPointer(this, declaringType); + return ReflectionAugments.GetFunctionPointer(this, declaringType); } [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/TypedReference.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/TypedReference.cs index 56e8ef05dd1cd3..6b096cc8080429 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/TypedReference.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/TypedReference.cs @@ -30,7 +30,7 @@ public static TypedReference MakeTypedReference(object target, FieldInfo[] flds) { Type type; int offset; - ReflectionAugments.ReflectionCoreCallbacks.MakeTypedReference(target, flds, out type, out offset); + ReflectionAugments.MakeTypedReference(target, flds, out type, out offset); return new TypedReference(target, offset, type.TypeHandle); }