Skip to content

Commit 18fc239

Browse files
eerhardtmdh1418
authored andcommitted
LambdaExpression.CanCompileToIL should respect IsDynamicCodeSupported (dotnet#80759)
* LambdaExpression.CanCompileToIL should respect IsDynamicCodeSupported With the new feature switch added in dotnet#39806, calling LambdaExpression.Compile is throwing a PlatformNotSupportedException. Instead, LambdaExpression should respect IsDynamicCodeSupported and switch to using the interpreter when IsDynamicCodeSupported is false. * Add tests
1 parent 6d1b552 commit 18fc239

File tree

3 files changed

+28
-3
lines changed

3 files changed

+28
-3
lines changed

src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LambdaExpression.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public abstract class LambdaExpression : Expression, IParameterProvider
2626
private readonly Expression _body;
2727

2828
// This can be flipped to false using feature switches at publishing time
29-
public static bool CanCompileToIL => true;
29+
public static bool CanCompileToIL => RuntimeFeature.IsDynamicCodeSupported;
3030

3131
// This could be flipped to false using feature switches at publishing time
3232
public static bool CanInterpret => true;
@@ -154,7 +154,7 @@ public Delegate Compile()
154154
/// <returns>A delegate containing the compiled version of the lambda.</returns>
155155
public Delegate Compile(bool preferInterpretation)
156156
{
157-
if (CanCompileToIL && CanInterpret && preferInterpretation)
157+
if (CanInterpret && preferInterpretation)
158158
{
159159
return new Interpreter.LightCompiler().CompileTop(this).CreateDelegate();
160160
}
@@ -234,7 +234,7 @@ internal Expression(Expression body)
234234
/// <returns>A delegate containing the compiled version of the lambda.</returns>
235235
public new TDelegate Compile(bool preferInterpretation)
236236
{
237-
if (CanCompileToIL && CanInterpret && preferInterpretation)
237+
if (CanInterpret && preferInterpretation)
238238
{
239239
return (TDelegate)(object)new Interpreter.LightCompiler().CompileTop(this).CreateDelegate();
240240
}

src/libraries/System.Linq.Expressions/tests/CompilerTests.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Runtime.CompilerServices;
55
using System.Text.RegularExpressions;
6+
using Microsoft.DotNet.RemoteExecutor;
67
using Xunit;
78

89
namespace System.Linq.Expressions.Tests
@@ -429,6 +430,29 @@ private static void Verify_VariableBinder_CatchBlock_Filter(CatchBlock @catch)
429430

430431
Assert.Throws<InvalidOperationException>(() => e.Compile());
431432
}
433+
434+
/// <summary>
435+
/// Verifies that compiling and executing a lambda method works when IsDynamicCodeSupported == false.
436+
/// </summary>
437+
[ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
438+
public static void CompileWorksWhenDynamicCodeNotSupported()
439+
{
440+
RemoteInvokeOptions options = new RemoteInvokeOptions();
441+
options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", false.ToString());
442+
443+
using RemoteInvokeHandle remoteHandle = RemoteExecutor.Invoke(static () =>
444+
{
445+
ParameterExpression param = Expression.Parameter(typeof(int));
446+
447+
Func<int, int> typedDel =
448+
Expression.Lambda<Func<int, int>>(Expression.Add(param, Expression.Constant(4)), param).Compile();
449+
Assert.Equal(304, typedDel(300));
450+
451+
Delegate del =
452+
Expression.Lambda(Expression.Add(param, Expression.Constant(5)), param).Compile();
453+
Assert.Equal(305, del.DynamicInvoke(300));
454+
}, options);
455+
}
432456
}
433457

434458
public enum ConstantsEnum

src/libraries/System.Linq.Expressions/tests/System.Linq.Expressions.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<TargetFrameworks>$(NetCoreAppCurrent);$(NetCoreAppCurrent)-ios;$(NetCoreAppCurrent)-tvos;$(NetCoreAppCurrent)-maccatalyst</TargetFrameworks>
4+
<IncludeRemoteExecutor>true</IncludeRemoteExecutor>
45
</PropertyGroup>
56

67
<ItemGroup>

0 commit comments

Comments
 (0)