Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get rid of reflection blocked types #85810

Merged
merged 6 commits into from
May 8, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions eng/testing/tests.singlefile.targets
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,6 @@
<ItemGroup Condition="'$(TestNativeAot)' == 'true'">
<RdXmlFile Include="$(MSBuildThisFileDirectory)default.rd.xml" />

<!-- Tests are doing private reflection. -->
<IlcArg Include="--nometadatablocking" />

<!-- xunit calls MakeGenericType to check if something is IEquatable -->
<IlcArg Include="--feature:System.Reflection.IsTypeConstructionEagerlyValidated=false" />
</ItemGroup>
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -888,10 +888,6 @@
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:System.Runtime.CompilerServices.ForceLazyDictionaryAttribute</Target>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:System.Runtime.CompilerServices.ReflectionBlockedAttribute</Target>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:System.Runtime.CompilerServices.StaticClassConstructionContext</Target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

namespace Internal.DeveloperExperience
{
[System.Runtime.CompilerServices.ReflectionBlocked]
public class DeveloperExperience
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@

namespace Internal.Reflection.Augments
{
[System.Runtime.CompilerServices.ReflectionBlocked]
public static class ReflectionAugments
{
//
Expand Down Expand Up @@ -117,7 +116,6 @@ internal static ReflectionCoreCallbacks ReflectionCoreCallbacks
// This class is implemented by Internal.Reflection.Core.dll and provides the actual implementation
// of Type.GetTypeInfo() and Assembly.Load().
//
[System.Runtime.CompilerServices.ReflectionBlocked]
public abstract class ReflectionCoreCallbacks
{
public abstract Assembly Load(AssemblyName refName, bool throwOnFileNotFound);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ namespace Internal.Reflection.Core
{
// Auto StructLayout used to suppress warning that order of fields is not guaranteed in partial structs
[StructLayout(LayoutKind.Auto)]
[ReflectionBlocked]
[CLSCompliant(false)]
public partial struct AssemblyBindResult
{
Expand All @@ -28,7 +27,6 @@ public partial struct AssemblyBindResult
//
// If the binder cannot locate an assembly, it must return null and set "exception" to an exception object.
//
[ReflectionBlocked]
[CLSCompliant(false)]
public abstract class AssemblyBinder
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ namespace Internal.Reflection.Core.Execution
//
// This singleton class acts as an entrypoint from System.Private.Reflection.Execution to System.Private.Reflection.Core.
//
[ReflectionBlocked]
[CLSCompliant(false)]
public sealed class ExecutionDomain
{
Expand Down Expand Up @@ -97,32 +96,23 @@ public MethodBase GetMethod(RuntimeTypeHandle declaringTypeHandle, QMethodDefini
// This group of methods jointly service the Type.GetTypeFromHandle() path. The caller
// is responsible for analyzing the RuntimeTypeHandle to figure out which flavor to call.
//=======================================================================================
public Type GetNamedTypeForHandle(RuntimeTypeHandle typeHandle, bool isGenericTypeDefinition)
public Type GetNamedTypeForHandle(RuntimeTypeHandle typeHandle)
{
QTypeDefinition qTypeDefinition;

if (ExecutionEnvironment.TryGetMetadataForNamedType(typeHandle, out qTypeDefinition))
{
QTypeDefinition qTypeDefinition = ExecutionEnvironment.GetMetadataForNamedType(typeHandle);
#if ECMA_METADATA_SUPPORT
if (qTypeDefinition.IsNativeFormatMetadataBased)
#endif
{
return qTypeDefinition.NativeFormatHandle.GetNamedType(qTypeDefinition.NativeFormatReader, typeHandle);
}
#if ECMA_METADATA_SUPPORT
else
{
return System.Reflection.Runtime.TypeInfos.EcmaFormat.EcmaFormatRuntimeNamedTypeInfo.GetRuntimeNamedTypeInfo(qTypeDefinition.EcmaFormatReader,
qTypeDefinition.EcmaFormatHandle,
typeHandle);
}
if (qTypeDefinition.IsNativeFormatMetadataBased)
#endif
{
return qTypeDefinition.NativeFormatHandle.GetNamedType(qTypeDefinition.NativeFormatReader, typeHandle);
}
#if ECMA_METADATA_SUPPORT
else
{
Debug.Assert(ExecutionEnvironment.IsReflectionBlocked(typeHandle) || RuntimeAugments.MightBeUnconstructedType(typeHandle));
return RuntimeBlockedTypeInfo.GetRuntimeBlockedTypeInfo(typeHandle, isGenericTypeDefinition);
return System.Reflection.Runtime.TypeInfos.EcmaFormat.EcmaFormatRuntimeNamedTypeInfo.GetRuntimeNamedTypeInfo(qTypeDefinition.EcmaFormatReader,
qTypeDefinition.EcmaFormatHandle,
typeHandle);
}
#endif
}

public Type GetArrayTypeForHandle(RuntimeTypeHandle typeHandle)
Expand Down Expand Up @@ -184,21 +174,6 @@ public Type GetConstructedGenericTypeForHandle(RuntimeTypeHandle typeHandle)
RuntimeTypeHandle[] genericTypeArgumentHandles;
genericTypeDefinitionHandle = RuntimeAugments.GetGenericInstantiation(typeHandle, out genericTypeArgumentHandles);

// Reflection blocked constructed generic types simply pretend to not be generic
// This is reasonable, as the behavior of reflection blocked types is supposed
// to be that they expose the minimal information about a type that is necessary
// for users of Object.GetType to move from that type to a type that isn't
// reflection blocked. By not revealing that reflection blocked types are generic
// we are making it appear as if implementation detail types exposed to user code
// are all non-generic, which is theoretically possible, and by doing so
// we avoid (in all known circumstances) the very complicated case of representing
// the interfaces, base types, and generic parameter types of reflection blocked
// generic type definitions.
if (ExecutionEnvironment.IsReflectionBlocked(genericTypeDefinitionHandle))
{
return RuntimeBlockedTypeInfo.GetRuntimeBlockedTypeInfo(typeHandle, isGenericTypeDefinition: false);
}

RuntimeTypeInfo genericTypeDefinition = genericTypeDefinitionHandle.GetTypeForRuntimeTypeHandle();
int count = genericTypeArgumentHandles.Length;
RuntimeTypeInfo[] genericTypeArguments = new RuntimeTypeInfo[count];
Expand Down Expand Up @@ -246,28 +221,6 @@ public RuntimeTypeHandle GetTypeHandleIfAvailable(Type type)
return runtimeType.InternalTypeHandleIfAvailable;
}

public bool SupportsReflection(Type type)
{
if (type is not RuntimeType)
return false;

if (ExecutionEnvironment.IsReflectionBlocked(type.TypeHandle))
{
// The type is an internal framework type and is blocked from reflection
return false;
}

RuntimeTypeInfo runtimeType = type.CastToRuntimeTypeInfo();
if (runtimeType.InternalFullNameOfAssembly == Internal.Runtime.Augments.RuntimeAugments.HiddenScopeAssemblyName)
{
// The type is an internal framework type but is reflectable for internal class library use
// where we make the type appear in a hidden assembly
return false;
}

return true;
}

public static bool IsPrimitiveType(Type type)
=> type == typeof(bool) || type == typeof(char)
|| type == typeof(sbyte) || type == typeof(byte)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ namespace Internal.Reflection.Core.Execution
// This class abstracts the underlying Redhawk (or whatever execution engine) runtime and exposes the services
// that I.R.Core.Execution needs.
//
[ReflectionBlocked]
[CLSCompliant(false)]
public abstract class ExecutionEnvironment
{
Expand All @@ -47,18 +46,14 @@ public abstract class ExecutionEnvironment
public abstract IEnumerable<RuntimeTypeHandle> TryGetImplementedInterfaces(RuntimeTypeHandle typeHandle);
public abstract void VerifyInterfaceIsImplemented(RuntimeTypeHandle typeHandle, RuntimeTypeHandle ifaceHandle);
public abstract void GetInterfaceMap(Type instanceType, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] Type interfaceType, out MethodInfo[] interfaceMethods, out MethodInfo[] targetMethods);
public abstract bool IsReflectionBlocked(RuntimeTypeHandle typeHandle);
public abstract string GetLastResortString(RuntimeTypeHandle typeHandle);

//==============================================================================================
// Reflection Mapping Tables
//==============================================================================================
public abstract bool TryGetMetadataForNamedType(RuntimeTypeHandle runtimeTypeHandle, out QTypeDefinition qTypeDefinition);
public abstract QTypeDefinition GetMetadataForNamedType(RuntimeTypeHandle runtimeTypeHandle);
public abstract bool TryGetNamedTypeForMetadata(QTypeDefinition qTypeDefinition, out RuntimeTypeHandle runtimeTypeHandle);

public abstract bool TryGetTypeReferenceForNamedType(RuntimeTypeHandle runtimeTypeHandle, out MetadataReader metadataReader, out TypeReferenceHandle typeRefHandle);
public abstract bool TryGetNamedTypeForTypeReference(MetadataReader metadataReader, TypeReferenceHandle typeRefHandle, out RuntimeTypeHandle runtimeTypeHandle);

public abstract bool TryGetArrayTypeForElementType(RuntimeTypeHandle elementTypeHandle, out RuntimeTypeHandle arrayTypeHandle);
public abstract bool TryGetArrayTypeElementType(RuntimeTypeHandle arrayTypeHandle, out RuntimeTypeHandle elementTypeHandle);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ namespace Internal.Reflection.Core.Execution
//
// This class abstracts the underlying Redhawk (or whatever execution engine) runtime that sets and gets fields.
//
[ReflectionBlocked]
[CLSCompliant(false)]
public abstract class FieldAccessor
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ namespace Internal.Reflection.Core.Execution
// This class polymorphically implements the MethodBase.Invoke() api and its close cousins. MethodInvokers are designed to be built once and cached
// for maximum Invoke() throughput.
//
[ReflectionBlocked]
public abstract class MethodInvoker
{
protected MethodInvoker() { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

namespace Internal.Reflection.Core.Execution
{
[ReflectionBlocked]
[CLSCompliant(false)]
public static class ReflectionCoreExecution
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,13 @@ public static Type GetRuntimeTypeBypassCache(EETypePtr eeType)

if (eeType.IsDefType)
{
if (eeType.IsGenericTypeDefinition)
{
return callbacks.GetNamedTypeForHandle(runtimeTypeHandle, isGenericTypeDefinition: true);
}
else if (eeType.IsGeneric)
if (eeType.IsGeneric)
{
return callbacks.GetConstructedGenericTypeForHandle(runtimeTypeHandle);
}
else
{
return callbacks.GetNamedTypeForHandle(runtimeTypeHandle, isGenericTypeDefinition: false);
return callbacks.GetNamedTypeForHandle(runtimeTypeHandle);
}
}
else if (eeType.IsArray)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

namespace Internal.Reflection.Core
{
[ReflectionBlocked]
[CLSCompliant(false)]
public abstract class ReflectionDomainSetup
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,15 @@
namespace Internal.Runtime.Augments
{
[CLSCompliant(false)]
[System.Runtime.CompilerServices.ReflectionBlocked]
public abstract class ReflectionExecutionDomainCallbacks
{
public abstract IntPtr TryGetStaticClassConstructionContext(RuntimeTypeHandle runtimeTypeHandle);

public abstract bool IsReflectionBlocked(RuntimeTypeHandle typeHandle);

//=======================================================================================
// This group of methods jointly service the Type.GetTypeFromHandle() path. The caller
// is responsible for analyzing the RuntimeTypeHandle to figure out which flavor to call.
//=======================================================================================
public abstract Type GetNamedTypeForHandle(RuntimeTypeHandle typeHandle, bool isGenericTypeDefinition);
public abstract Type GetNamedTypeForHandle(RuntimeTypeHandle typeHandle);
public abstract Type GetArrayTypeForHandle(RuntimeTypeHandle typeHandle);
public abstract Type GetMdArrayTypeForHandle(RuntimeTypeHandle typeHandle, int rank);
public abstract Type GetPointerTypeForHandle(RuntimeTypeHandle typeHandle);
Expand All @@ -49,7 +46,6 @@ public abstract class ReflectionExecutionDomainCallbacks
public abstract Assembly GetAssemblyForHandle(RuntimeTypeHandle typeHandle);

public abstract RuntimeTypeHandle GetTypeHandleIfAvailable(Type type);
public abstract bool SupportsReflection(Type type);

public abstract MethodInfo GetDelegateMethod(Delegate del);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ namespace Internal.Runtime.Augments
using BinderBundle = System.Reflection.BinderBundle;
using Pointer = System.Reflection.Pointer;

[ReflectionBlocked]
public static class RuntimeAugments
{
/// <summary>
Expand Down Expand Up @@ -445,15 +444,6 @@ public static RuntimeTypeHandle ProjectionTypeForArrays
}
}

//
// Returns the name of a virtual assembly we dump types private class library-Reflectable ty[es for internal class library use.
// The assembly binder visible to apps will never reveal this assembly.
//
// Note that this is not versionable as it is exposed as a const (and needs to be a const so we can used as a custom attribute argument - which
// is the other reason this string is not versionable.)
//
public const string HiddenScopeAssemblyName = "HiddenScope, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

//
// This implements the "IsAssignableFrom()" api for runtime-created types. By policy, we let the underlying runtime decide assignability.
//
Expand Down Expand Up @@ -504,9 +494,6 @@ public static IEnumerable<RuntimeTypeHandle> TryGetImplementedInterfaces(Runtime
{
EETypePtr ifcEEType = eeType.Interfaces[i];
RuntimeTypeHandle ifcrth = new RuntimeTypeHandle(ifcEEType);
if (Callbacks.IsReflectionBlocked(ifcrth))
continue;

implementedInterfaces.Add(ifcrth);
}
return implementedInterfaces.ToArray();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ namespace Internal.Runtime.Augments
/// Internal.Runtime.Augments.RuntimeAugments.InitializeStackTraceMetadataSupport(StackTraceMetadataCallbacks callbacks);
///
/// </summary>
[System.Runtime.CompilerServices.ReflectionBlocked]
[CLSCompliant(false)]
public abstract class StackTraceMetadataCallbacks
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
namespace Internal.Runtime.Augments
{
[CLSCompliant(false)]
[System.Runtime.CompilerServices.ReflectionBlocked]
public abstract class TypeLoaderCallbacks
{
public abstract TypeManagerHandle GetModuleForMetadataReader(MetadataReader reader);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

namespace Internal.Runtime.CompilerServices
{
[System.Runtime.CompilerServices.ReflectionBlocked]
public static class FunctionPointerOps
{
#if TARGET_WASM
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

namespace Internal.Runtime.CompilerServices
{
[System.Runtime.CompilerServices.ReflectionBlocked]
public struct GenericMethodDescriptor
{
public readonly IntPtr MethodFunctionPointer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ namespace Internal.Runtime.CompilerServices
// so that repeated allocation of the same resolver will not leak.
// 3) Use the ResolveMethod function to do the virtual lookup. This function takes advantage of
// a lockless cache so the resolution is very fast for repeated lookups.
[ReflectionBlocked]
public struct OpenMethodResolver : IEquatable<OpenMethodResolver>
{
// Lazy initialized to point to the type loader method when the first `GVMResolve` resolver is created
Expand Down
Loading