Skip to content

Commit

Permalink
Do not root array methods in dataflow analysis (#602)
Browse files Browse the repository at this point in the history
Methods on arrays are very special.
  • Loading branch information
MichalStrehovsky committed Jan 28, 2021
1 parent e28a392 commit d47918d
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ public static IEnumerable<TypeSystemEntity> GetDynamicallyAccessedMembers(this T

public static IEnumerable<MethodDesc> GetConstructorsOnType(this TypeDesc type, Func<MethodDesc, bool> filter, BindingFlags? bindingFlags = null)
{
if (type.IsArray)
{
// Constructors on arrays are special magic that the reflection stack special cases at runtime anyway.
yield break;
}

foreach (var method in type.GetMethods())
{
if (!method.IsConstructor)
Expand Down Expand Up @@ -124,6 +130,14 @@ public static IEnumerable<MethodDesc> GetConstructorsOnType(this TypeDesc type,
public static IEnumerable<MethodDesc> GetMethodsOnTypeHierarchy(this TypeDesc type, Func<MethodDesc, bool> filter, BindingFlags? bindingFlags = null)
{
bool onBaseType = false;

if (type.IsArray)
{
// Methods on arrays are special magic that the reflection stack special cases at runtime anyway.
type = type.BaseType;
onBaseType = true;
}

while (type != null)
{
foreach (var method in type.GetMethods())
Expand Down Expand Up @@ -230,15 +244,18 @@ public static IEnumerable<MetadataType> GetNestedTypesOnType(this TypeDesc type,
public static IEnumerable<PropertyPseudoDesc> GetPropertiesOnTypeHierarchy(this TypeDesc type, Func<PropertyPseudoDesc, bool> filter, BindingFlags? bindingFlags = BindingFlags.Default)
{
bool onBaseType = false;

if (type.IsArray)
{
type = type.BaseType;
onBaseType = true;
}

while (type != null)
{
if (type.GetTypeDefinition() is not EcmaType ecmaType)
if (type is not EcmaType ecmaType)
{
// Go down the inheritance chain to see if we have an EcmaType later.
// Arrays would hit this (base type of arrays is the EcmaType for System.Array).
type = type.BaseType;
onBaseType = true;
continue;
yield break;
}

foreach (var propertyHandle in ecmaType.MetadataReader.GetTypeDefinition(ecmaType.Handle).GetProperties())
Expand Down Expand Up @@ -292,15 +309,18 @@ public static IEnumerable<PropertyPseudoDesc> GetPropertiesOnTypeHierarchy(this
public static IEnumerable<EventPseudoDesc> GetEventsOnTypeHierarchy(this TypeDesc type, Func<EventPseudoDesc, bool> filter, BindingFlags? bindingFlags = BindingFlags.Default)
{
bool onBaseType = false;

if (type.IsArray)
{
type = type.BaseType;
onBaseType = true;
}

while (type != null)
{
if (type.GetTypeDefinition() is not EcmaType ecmaType)
if (type is not EcmaType ecmaType)
{
// Go down the inheritance chain to see if we have an EcmaType later.
// Arrays would hit this (base type of arrays is the EcmaType for System.Array).
type = type.BaseType;
onBaseType = true;
continue;
yield break;
}

foreach (var eventHandle in ecmaType.MetadataReader.GetTypeDefinition(ecmaType.Handle).GetEvents())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,10 @@ public static bool IsMethodSupportedInReflectionInvoke(MethodDesc method)
if (owningType.IsNullable)
return false;

// Methods on arrays are special cased in the runtime reflection
if (owningType.IsArray)
return false;

// Finalizers are not reflection invokable
if (method.IsFinalizer)
return false;
Expand Down
3 changes: 3 additions & 0 deletions src/tests/nativeaot/SmokeTests/Dataflow/Dataflow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,9 @@ public static void Run()
// This test might be a bit fragile, but we want to make sure accessing properties
// on an array triggers same as accessing properties on System.Array.
Assert.Equal(7, typeof(int[]).GetProperties().Length);

// Regression test for when dataflow analysis was trying to generate method bodies for these
Assert.Equal(1, typeof(int[]).GetConstructors().Length);
}
}
}
Expand Down

0 comments on commit d47918d

Please sign in to comment.