未验证 提交 5eb50a52 编写于 作者: E Eric Erhardt 提交者: GitHub

Resolve ILLink warnings in System.Linq.Expressions (Round 2) (#47803)

* Resolve ILLink warnings in System.Linq.Expressions (Round 2)

Contributes to #45623

* Suppress ToString warning in ExpressionStringBuilder
上级 469df595
......@@ -19,36 +19,6 @@
<property name="Scope">member</property>
<property name="Target">M:System.Dynamic.Utils.TypeExtensions.GetAnyStaticMethodValidated(System.Type,System.String,System.Type[])</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2070</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Linq.Expressions.Compiler.LambdaCompiler.EmitGetArrayElement(System.Type)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2070</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Linq.Expressions.Compiler.LambdaCompiler.EmitLift(System.Linq.Expressions.ExpressionType,System.Type,System.Linq.Expressions.MethodCallExpression,System.Linq.Expressions.ParameterExpression[],System.Linq.Expressions.Expression[])</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2070</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Linq.Expressions.Compiler.LambdaCompiler.EmitLiftedBinaryArithmetic(System.Linq.Expressions.ExpressionType,System.Type,System.Type,System.Type)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2070</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Linq.Expressions.Compiler.LambdaCompiler.EmitSetArrayElement(System.Type)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2070</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Linq.Expressions.Compiler.LambdaCompiler.EmitUnaryOperator(System.Linq.Expressions.ExpressionType,System.Type,System.Type)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2072</argument>
......@@ -79,36 +49,6 @@
<property name="Scope">member</property>
<property name="Target">M:System.Dynamic.Utils.TypeUtils.GetUserDefinedCoercionMethod(System.Type,System.Type)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2075</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Linq.Expressions.Compiler.LambdaCompiler.AddressOf(System.Linq.Expressions.IndexExpression,System.Type)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2075</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Linq.Expressions.Compiler.LambdaCompiler.AddressOf(System.Linq.Expressions.MethodCallExpression,System.Type)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2075</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Linq.Expressions.Compiler.LambdaCompiler.EmitDynamicExpression(System.Linq.Expressions.Expression)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2075</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Linq.Expressions.Compiler.LambdaCompiler.EmitInvocationExpression(System.Linq.Expressions.Expression,System.Linq.Expressions.Compiler.LambdaCompiler.CompilationFlags)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2075</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Linq.Expressions.Compiler.LambdaCompiler.EmitUnary(System.Linq.Expressions.UnaryExpression,System.Linq.Expressions.Compiler.LambdaCompiler.CompilationFlags)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2075</argument>
......@@ -139,65 +79,5 @@
<property name="Scope">member</property>
<property name="Target">M:System.Linq.Expressions.Expression.PropertyOrField(System.Linq.Expressions.Expression,System.String)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2075</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Linq.Expressions.ExpressionStringBuilder.VisitExtension(System.Linq.Expressions.Expression)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2075</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Linq.Expressions.Interpreter.LightCompiler.CompileAddress(System.Linq.Expressions.Expression,System.Int32)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2075</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Linq.Expressions.Interpreter.LightCompiler.CompileIndexAssignment(System.Linq.Expressions.BinaryExpression,System.Boolean)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2075</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Linq.Expressions.Interpreter.LightCompiler.CompileInvocationExpression(System.Linq.Expressions.Expression)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2075</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Linq.Expressions.Interpreter.LightCompiler.CompileMultiDimArrayAccess(System.Linq.Expressions.Expression,System.Linq.Expressions.IArgumentProvider,System.Int32)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2075</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Linq.Expressions.Interpreter.LightCompiler.EmitIndexGet(System.Linq.Expressions.IndexExpression)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2077</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Linq.Expressions.Interpreter.DefaultValueInstruction.Run(System.Linq.Expressions.Interpreter.InterpretedFrame)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2077</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Linq.Expressions.Interpreter.InitializeLocalInstruction.MutableBox.Run(System.Linq.Expressions.Interpreter.InterpretedFrame)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2077</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Linq.Expressions.Interpreter.InitializeLocalInstruction.MutableValue.Run(System.Linq.Expressions.Interpreter.InterpretedFrame)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2080</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Linq.Expressions.Compiler.CompilerScope.ElementBoxStorage.#ctor(System.Linq.Expressions.Compiler.CompilerScope.Storage,System.Int32,System.Linq.Expressions.ParameterExpression)</property>
</attribute>
</assembly>
</linker>
......@@ -29,6 +29,17 @@ public static Type GetNullableType(this Type type)
return type;
}
[DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(Nullable<>))]
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
Justification = "The Nullable<T> ctor will be preserved by the DynamicDependency.")]
public static ConstructorInfo GetNullableConstructor(Type nullableType, Type nonNullableType)
{
Debug.Assert(nullableType.IsNullableType());
Debug.Assert(!nonNullableType.IsNullableType() && nonNullableType.IsValueType);
return nullableType.GetConstructor(new Type[] { nonNullableType })!;
}
public static bool IsNullableType(this Type type) => type.IsConstructedGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
public static bool IsNullableOrReferenceType(this Type type) => !type.IsValueType || IsNullableType(type);
......@@ -934,5 +945,29 @@ internal static bool IsFloatingPoint(this TypeCode typeCode)
}
#endif
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
Justification = "The Array 'Get' method is dynamically constructed and is not included in IL. It is not subject to trimming.")]
public static MethodInfo GetArrayGetMethod(Type arrayType)
{
Debug.Assert(arrayType.IsArray);
return arrayType.GetMethod("Get", BindingFlags.Public | BindingFlags.Instance)!;
}
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
Justification = "The Array 'Set' method is dynamically constructed and is not included in IL. It is not subject to trimming.")]
public static MethodInfo GetArraySetMethod(Type arrayType)
{
Debug.Assert(arrayType.IsArray);
return arrayType.GetMethod("Set", BindingFlags.Public | BindingFlags.Instance)!;
}
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
Justification = "The Array 'Address' method is dynamically constructed and is not included in IL. It is not subject to trimming.")]
public static MethodInfo GetArrayAddressMethod(Type arrayType)
{
Debug.Assert(arrayType.IsArray);
return arrayType.GetMethod("Address", BindingFlags.Public | BindingFlags.Instance)!;
}
}
}
......@@ -110,8 +110,9 @@ internal ElementBoxStorage(Storage array, int index, ParameterExpression variabl
{
_array = array;
_index = index;
_boxType = typeof(StrongBox<>).MakeGenericType(variable.Type);
_boxValueField = _boxType.GetField("Value")!;
Type boxType = typeof(StrongBox<>).MakeGenericType(variable.Type);
_boxValueField = boxType.GetField("Value")!;
_boxType = boxType;
}
internal override void EmitLoad()
......
......@@ -485,7 +485,7 @@ private static bool TryEmitILConstant(this ILGenerator il, object value, Type ty
if (TryEmitILConstant(il, value, nonNullType))
{
il.Emit(OpCodes.Newobj, GetNullableConstructor(type, nonNullType));
il.Emit(OpCodes.Newobj, TypeUtils.GetNullableConstructor(type, nonNullType));
return true;
}
......@@ -826,7 +826,7 @@ private static void EmitNullableToNullableConversion(this ILGenerator il, Type t
Type nnTypeTo = typeTo.GetNonNullableType();
il.EmitConvertToType(nnTypeFrom, nnTypeTo, isChecked, locals);
// construct result type
ConstructorInfo ci = GetNullableConstructor(typeTo, nnTypeTo);
ConstructorInfo ci = TypeUtils.GetNullableConstructor(typeTo, nnTypeTo);
il.Emit(OpCodes.Newobj, ci);
labEnd = il.DefineLabel();
il.Emit(OpCodes.Br_S, labEnd);
......@@ -846,21 +846,10 @@ private static void EmitNonNullableToNullableConversion(this ILGenerator il, Typ
Debug.Assert(typeTo.IsNullableType());
Type nnTypeTo = typeTo.GetNonNullableType();
il.EmitConvertToType(typeFrom, nnTypeTo, isChecked, locals);
ConstructorInfo ci = GetNullableConstructor(typeTo, nnTypeTo);
ConstructorInfo ci = TypeUtils.GetNullableConstructor(typeTo, nnTypeTo);
il.Emit(OpCodes.Newobj, ci);
}
[DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(Nullable<>))]
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
Justification = "The Nullable<T> ctor will be preserved by the DynamicDependency.")]
private static ConstructorInfo GetNullableConstructor(Type nullableType, Type nonNullableType)
{
Debug.Assert(nullableType.IsNullableType());
Debug.Assert(!nonNullableType.IsNullableType() && nonNullableType.IsValueType);
return nullableType.GetConstructor(new Type[] { nonNullableType })!;
}
private static void EmitNullableToNonNullableConversion(this ILGenerator il, Type typeFrom, Type typeTo, bool isChecked, ILocalCache locals)
{
Debug.Assert(typeFrom.IsNullableType());
......
......@@ -162,7 +162,6 @@ private void EmitMemberAddress(MemberInfo member, Type? objectType)
_ilg.Emit(OpCodes.Ldloca, temp);
}
private void AddressOf(MethodCallExpression node, Type type)
{
// An array index of a multi-dimensional array is represented by a call to Array.Get,
......@@ -172,9 +171,9 @@ private void AddressOf(MethodCallExpression node, Type type)
// this situation and replace it with a call to the Address method.
if (!node.Method.IsStatic &&
node.Object!.Type.IsArray &&
node.Method == node.Object.Type.GetMethod("Get", BindingFlags.Public | BindingFlags.Instance))
node.Method == TypeUtils.GetArrayGetMethod(node.Object.Type))
{
MethodInfo mi = node.Object.Type.GetMethod("Address", BindingFlags.Public | BindingFlags.Instance)!;
MethodInfo mi = TypeUtils.GetArrayAddressMethod(node.Object.Type);
EmitMethodCall(node.Object, mi, node);
}
......@@ -200,7 +199,7 @@ private void AddressOf(IndexExpression node, Type type)
}
else
{
MethodInfo address = node.Object!.Type.GetMethod("Address", BindingFlags.Public | BindingFlags.Instance)!;
MethodInfo address = TypeUtils.GetArrayAddressMethod(node.Object!.Type);
EmitMethodCall(node.Object, address, node);
}
}
......
......@@ -475,10 +475,12 @@ private void EmitLiftedBinaryArithmetic(ExpressionType op, Type leftType, Type r
FreeLocal(locLeft);
FreeLocal(locRight);
EmitBinaryOperator(op, leftType.GetNonNullableType(), rightType.GetNonNullableType(), resultType.GetNonNullableType(), liftedToNull: false);
Type resultNonNullableType = resultType.GetNonNullableType();
EmitBinaryOperator(op, leftType.GetNonNullableType(), rightType.GetNonNullableType(), resultNonNullableType, liftedToNull: false);
// construct result type
ConstructorInfo ci = resultType.GetConstructor(new Type[] { resultType.GetNonNullableType() })!;
ConstructorInfo ci = TypeUtils.GetNullableConstructor(resultType, resultNonNullableType);
_ilg.Emit(OpCodes.Newobj, ci);
_ilg.Emit(OpCodes.Stloc, locResult);
_ilg.Emit(OpCodes.Br_S, labEnd);
......
......@@ -4,9 +4,11 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Dynamic.Utils;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
namespace System.Linq.Expressions.Compiler
{
......@@ -183,7 +185,7 @@ private void EmitInvocationExpression(Expression expr, CompilationFlags flags)
if (typeof(LambdaExpression).IsAssignableFrom(expr.Type))
{
// if the invoke target is a lambda expression tree, first compile it into a delegate
expr = Expression.Call(expr, expr.Type.GetMethod("Compile", Type.EmptyTypes)!);
expr = Expression.Call(expr, LambdaExpression.GetCompileMethod(expr.Type));
}
EmitMethodCall(expr, expr.Type.GetInvokeMethod(), node, CompilationFlags.EmitAsNoTail | CompilationFlags.EmitExpressionStart);
......@@ -311,7 +313,7 @@ private void EmitGetArrayElement(Type arrayType)
else
{
// Multidimensional arrays, call get
_ilg.Emit(OpCodes.Call, arrayType.GetMethod("Get", BindingFlags.Public | BindingFlags.Instance)!);
_ilg.Emit(OpCodes.Call, TypeUtils.GetArrayGetMethod(arrayType));
}
}
......@@ -339,7 +341,7 @@ private void EmitSetArrayElement(Type arrayType)
else
{
// Multidimensional arrays, call set
_ilg.Emit(OpCodes.Call, arrayType.GetMethod("Set", BindingFlags.Public | BindingFlags.Instance)!);
_ilg.Emit(OpCodes.Call, TypeUtils.GetArraySetMethod(arrayType));
}
}
......@@ -602,7 +604,7 @@ private void EmitDynamicExpression(Expression expr)
_ilg.Emit(OpCodes.Dup);
LocalBuilder siteTemp = GetLocal(siteType);
_ilg.Emit(OpCodes.Stloc, siteTemp);
_ilg.Emit(OpCodes.Ldfld, siteType.GetField("Target")!);
_ilg.Emit(OpCodes.Ldfld, GetCallSiteTargetField(siteType));
_ilg.Emit(OpCodes.Ldloc, siteTemp);
FreeLocal(siteTemp);
......@@ -611,6 +613,15 @@ private void EmitDynamicExpression(Expression expr)
EmitWriteBack(wb);
}
[DynamicDependency("Target", typeof(CallSite<>))]
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
Justification = "The 'Target' field will be preserved by the DynamicDependency.")]
private static FieldInfo GetCallSiteTargetField(Type siteType)
{
Debug.Assert(siteType.IsGenericType && siteType.GetGenericTypeDefinition() == typeof(CallSite<>));
return siteType.GetField("Target")!;
}
private void EmitNewExpression(Expression expr)
{
NewExpression node = (NewExpression)expr;
......@@ -1160,7 +1171,7 @@ private void EmitLift(ExpressionType nodeType, Type resultType, MethodCallExpres
EmitMethodCallExpression(mc);
if (resultType.IsNullableType() && !TypeUtils.AreEquivalent(resultType, mc.Type))
{
ConstructorInfo ci = resultType.GetConstructor(new Type[] { mc.Type })!;
ConstructorInfo ci = TypeUtils.GetNullableConstructor(resultType, mc.Type);
_ilg.Emit(OpCodes.Newobj, ci);
}
_ilg.Emit(OpCodes.Br_S, exit);
......@@ -1264,7 +1275,7 @@ private void EmitLift(ExpressionType nodeType, Type resultType, MethodCallExpres
EmitMethodCallExpression(mc);
if (resultType.IsNullableType() && !TypeUtils.AreEquivalent(resultType, mc.Type))
{
ConstructorInfo ci = resultType.GetConstructor(new Type[] { mc.Type })!;
ConstructorInfo ci = TypeUtils.GetNullableConstructor(resultType, mc.Type);
_ilg.Emit(OpCodes.Newobj, ci);
}
_ilg.Emit(OpCodes.Br_S, exit);
......
......@@ -94,7 +94,7 @@ private void EmitUnary(UnaryExpression node, CompilationFlags flags)
EmitBinaryOperator(ExpressionType.SubtractChecked, nnType, nnType, nnType, liftedToNull: false);
// construct result
_ilg.Emit(OpCodes.Newobj, type.GetConstructor(new Type[] { nnType })!);
_ilg.Emit(OpCodes.Newobj, TypeUtils.GetNullableConstructor(type, nnType));
_ilg.Emit(OpCodes.Br_S, end);
// if null then push back on stack
......@@ -164,7 +164,7 @@ private void EmitUnaryOperator(ExpressionType op, Type operandType, Type resultT
EmitUnaryOperator(op, nnOperandType, nnOperandType);
// construct result
ConstructorInfo ci = resultType.GetConstructor(new Type[] { nnOperandType })!;
ConstructorInfo ci = TypeUtils.GetNullableConstructor(resultType, nnOperandType);
_ilg.Emit(OpCodes.Newobj, ci);
_ilg.Emit(OpCodes.Br_S, labEnd);
......
......@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
......@@ -786,6 +787,8 @@ protected internal override Expression VisitIndex(IndexExpression node)
return node;
}
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2075:UnrecognizedReflectionPattern",
Justification = "The 'ToString' method cannot be trimmed on any Expression type because we are calling Expression.ToString() in this method.")]
protected internal override Expression VisitExtension(Expression node)
{
// Prefer an overridden ToString, if available.
......
......@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Dynamic.Utils;
namespace System.Linq.Expressions.Interpreter
......@@ -21,6 +22,8 @@ internal DefaultValueInstruction(Type type)
public override string InstructionName => "DefaultValue";
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2077:UnrecognizedReflectionPattern",
Justification = "_type is a ValueType. You can always create an instance of a ValueType.")]
public override int Run(InterpretedFrame frame)
{
frame.Push(Activator.CreateInstance(_type));
......
......@@ -593,7 +593,7 @@ private void EmitIndexGet(IndexExpression index)
}
else if (index.ArgumentCount != 1)
{
_instructions.EmitCall(index.Object!.Type.GetMethod("Get", BindingFlags.Public | BindingFlags.Instance)!);
_instructions.EmitCall(TypeUtils.GetArrayGetMethod(index.Object!.Type));
}
else
{
......@@ -632,7 +632,7 @@ private void CompileIndexAssignment(BinaryExpression node, bool asVoid)
}
else if (index.ArgumentCount != 1)
{
_instructions.EmitCall(index.Object!.Type.GetMethod("Set", BindingFlags.Public | BindingFlags.Instance)!);
_instructions.EmitCall(TypeUtils.GetArraySetMethod(index.Object!.Type));
}
else
{
......@@ -2343,7 +2343,7 @@ private static bool ShouldWritebackNode(Expression node)
var call = (MethodCallExpression)node;
if (!call.Method.IsStatic &&
call.Object!.Type.IsArray &&
call.Method == call.Object.Type.GetMethod("Get", BindingFlags.Public | BindingFlags.Instance))
call.Method == TypeUtils.GetArrayGetMethod(call.Object.Type))
{
return CompileMultiDimArrayAccess(
call.Object,
......@@ -2380,9 +2380,9 @@ private ByRefUpdater CompileMultiDimArrayAccess(Expression array, IArgumentProvi
indexLocals[i] = argTmp;
}
_instructions.EmitCall(array.Type.GetMethod("Get", BindingFlags.Public | BindingFlags.Instance)!);
_instructions.EmitCall(TypeUtils.GetArrayGetMethod(array.Type));
return new IndexMethodByRefUpdater(objTmp, indexLocals, array.Type.GetMethod("Set", BindingFlags.Public | BindingFlags.Instance)!, index);
return new IndexMethodByRefUpdater(objTmp, indexLocals, TypeUtils.GetArraySetMethod(array.Type), index);
}
private void CompileNewExpression(Expression expr)
......@@ -2671,7 +2671,7 @@ private void CompileInvocationExpression(Expression expr)
if (typeof(LambdaExpression).IsAssignableFrom(node.Expression.Type))
{
MethodInfo compMethod = node.Expression.Type.GetMethod("Compile", Type.EmptyTypes)!;
MethodInfo compMethod = LambdaExpression.GetCompileMethod(node.Expression.Type);
CompileMethodCallExpression(
Expression.Call(
node.Expression,
......
......@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Dynamic.Utils;
using System.Reflection;
using System.Runtime.CompilerServices;
......@@ -373,9 +374,13 @@ internal sealed class MutableValue : InitializeLocalInstruction, IBoxableInstruc
internal MutableValue(int index, Type type)
: base(index)
{
Debug.Assert(type.IsValueType, "MutableValue only supports value types.");
_type = type;
}
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2077:UnrecognizedReflectionPattern",
Justification = "_type is a ValueType. You can always create an instance of a ValueType.")]
public override int Run(InterpretedFrame frame)
{
try
......@@ -406,9 +411,13 @@ internal sealed class MutableBox : InitializeLocalInstruction
internal MutableBox(int index, Type type)
: base(index)
{
Debug.Assert(type.IsValueType, "MutableBox only supports value types.");
_type = type;
}
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2077:UnrecognizedReflectionPattern",
Justification = "_type is a ValueType. You can always create an instance of a ValueType.")]
public override int Run(InterpretedFrame frame)
{
object? value;
......
......@@ -102,6 +102,39 @@ internal virtual int ParameterCount
}
}
/// <summary>
/// Gets the Compile() MethodInfo on the specified LambdaExpression type.
/// </summary>
/// <remarks>
/// Note that Expression{TDelegate} defines a 'new' Compile() method that hides the base
/// LambdaExpression.Compile() method.
/// </remarks>
internal static MethodInfo GetCompileMethod(Type lambdaExpressionType)
{
Debug.Assert(lambdaExpressionType.IsAssignableTo(typeof(LambdaExpression)));
if (lambdaExpressionType == typeof(LambdaExpression))
{
// use a hard-coded type directly so the method doesn't get trimmed
return typeof(LambdaExpression).GetMethod("Compile", Type.EmptyTypes)!;
}
return GetDerivedCompileMethod(lambdaExpressionType);
}
[DynamicDependency("Compile()", typeof(Expression<>))]
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
Justification = "The 'Compile' method will be preserved by the DynamicDependency.")]
private static MethodInfo GetDerivedCompileMethod(Type lambdaExpressionType)
{
Debug.Assert(lambdaExpressionType.IsAssignableTo(typeof(LambdaExpression)) && lambdaExpressionType != typeof(LambdaExpression));
MethodInfo result = lambdaExpressionType.GetMethod("Compile", Type.EmptyTypes)!;
Debug.Assert(result.DeclaringType!.IsGenericType && result.DeclaringType.GetGenericTypeDefinition() == typeof(Expression<>));
return result;
}
/// <summary>
/// Produces a delegate that represents the lambda expression.
/// </summary>
......
......@@ -1401,8 +1401,6 @@ public static MethodCallExpression ArrayIndex(Expression array, params Expressio
/// <paramref name="array"/> or <paramref name="indexes"/> is null.</exception>
/// <exception cref="ArgumentException">
/// <paramref name="array"/>.Type does not represent an array type.-or-The rank of <paramref name="array"/>.Type does not match the number of elements in <paramref name="indexes"/>.-or-The <see cref="Expression.Type"/> property of one or more elements of <paramref name="indexes"/> does not represent the <see cref="int"/> type.</exception>
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2075:UnrecognizedReflectionPattern",
Justification = "The Array 'Get' method is dynamically constructed and are not included in IL. It is not subject to trimming.")]
public static MethodCallExpression ArrayIndex(Expression array, IEnumerable<Expression> indexes)
{
ExpressionUtils.RequiresCanRead(array, nameof(array), -1);
......@@ -1431,7 +1429,7 @@ public static MethodCallExpression ArrayIndex(Expression array, IEnumerable<Expr
}
}
MethodInfo mi = array.Type.GetMethod("Get", BindingFlags.Public | BindingFlags.Instance)!;
MethodInfo mi = TypeUtils.GetArrayGetMethod(array.Type);
return Call(array, mi, indexList);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册