未验证 提交 07b57418 编写于 作者: M Michal Strehovský 提交者: GitHub

Generate method bodies for delegate Invoke methods (#70883)


There is a dataflow warning suppression in System.Linq.Expressions that assumes we'll always have an invocable method body for delegate Invoke method. We need one in IL. We don't in native code.

Emulate what IL Linker does and generate a method body. This is a size regression.

Suppression: https://github.com/dotnet/runtime/blob/3b2883b097a773715ca84056885e0ca1488da36e/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L906-L912

Fixes #70880.
上级 8a6672ae
......@@ -46,11 +46,14 @@ public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFacto
var mdManager = (UsageBasedMetadataManager)factory.MetadataManager;
if (_type.IsDelegate)
{
// A delegate type metadata is rather useless without the Invoke method.
// If someone reflects on a delegate, chances are they're going to look at the signature.
// We've decided as a policy that delegate Invoke methods will be generated in full.
// The libraries (e.g. System.Linq.Expressions) have trimming warning suppressions
// in places where they assume IL-level trimming (where the method cannot be removed).
// We ask for a full reflectable method with its method body instead of just the
// metadata.
var invokeMethod = _type.GetMethod("Invoke", null);
if (!mdManager.IsReflectionBlocked(invokeMethod))
dependencies.Add(factory.MethodMetadata(invokeMethod), "Delegate invoke method metadata");
dependencies.Add(factory.ReflectableMethod(invokeMethod), "Delegate invoke method");
}
if (_type.IsEnum)
......
......@@ -9,6 +9,7 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Reflection;
......@@ -31,6 +32,7 @@ private static int Main()
TestVirtualDelegateTargets.Run();
TestRunClassConstructor.Run();
TestFieldMetadata.Run();
TestLinqInvocation.Run();
#if !OPTIMIZED_MODE_WITHOUT_SCANNER
TestContainment.Run();
TestInterfaceMethod.Run();
......@@ -1859,6 +1861,19 @@ public static void Run()
}
}
class TestLinqInvocation
{
delegate void RunMeDelegate();
static void RunMe() { }
public static void Run()
{
Expression<Action<RunMeDelegate>> ex = (RunMeDelegate m) => m();
ex.Compile()(RunMe);
}
}
class TestRunClassConstructor
{
static class TypeWithNoStaticFieldsButACCtor
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册