Skip to content

Commit d059e9a

Browse files
committed
add the test for #472 and support the interpreter for the logical expressions
1 parent 69d41f2 commit d059e9a

File tree

3 files changed

+80
-24
lines changed

3 files changed

+80
-24
lines changed

src/FastExpressionCompiler/FastExpressionCompiler.cs

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2031,9 +2031,6 @@ public static bool TryEmit(Expression expr,
20312031
case ExpressionType.TypeEqual:
20322032
return TryEmitTypeIsOrEqual((TypeBinaryExpression)expr, paramExprs, il, ref closure, setup, parent);
20332033

2034-
case ExpressionType.Not:
2035-
return TryEmitNot((UnaryExpression)expr, paramExprs, il, ref closure, setup, parent);
2036-
20372034
case ExpressionType.Convert:
20382035
case ExpressionType.ConvertChecked:
20392036
return TryEmitConvert((UnaryExpression)expr, paramExprs, il, ref closure, setup, parent);
@@ -2088,16 +2085,17 @@ public static bool TryEmit(Expression expr,
20882085
case ExpressionType.LessThanOrEqual:
20892086
case ExpressionType.Equal:
20902087
case ExpressionType.NotEqual:
2091-
if ((setup & CompilerFlags.DisableInterpreter) == 0 && exprType.IsPrimitive &&
2092-
Interpreter.TryInterpretBoolean(out var boolResult, expr))
20932088
{
2094-
if ((parent & ParentFlags.IgnoreResult) == 0)
2095-
il.Demit(boolResult ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
2096-
return true;
2089+
if ((setup & CompilerFlags.DisableInterpreter) == 0 && exprType.IsPrimitive &&
2090+
Interpreter.TryInterpretBoolean(out var boolResult, expr))
2091+
{
2092+
if ((parent & ParentFlags.IgnoreResult) == 0)
2093+
il.Demit(boolResult ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
2094+
return true;
2095+
}
2096+
return TryEmitComparison(((BinaryExpression)expr).Left, ((BinaryExpression)expr).Right, exprType, nodeType, paramExprs, il,
2097+
ref closure, setup, parent);
20972098
}
2098-
return TryEmitComparison(((BinaryExpression)expr).Left, ((BinaryExpression)expr).Right, exprType, nodeType, paramExprs, il,
2099-
ref closure, setup, parent);
2100-
21012099
case ExpressionType.Add:
21022100
case ExpressionType.AddChecked:
21032101
case ExpressionType.Subtract:
@@ -2106,32 +2104,50 @@ public static bool TryEmit(Expression expr,
21062104
case ExpressionType.MultiplyChecked:
21072105
case ExpressionType.Divide:
21082106
case ExpressionType.Modulo:
2109-
if ((setup & CompilerFlags.DisableInterpreter) == 0 && exprType.IsPrimitive &&
2110-
Interpreter.TryInterpret(out var resultObj, expr))
21112107
{
2112-
if ((parent & ParentFlags.IgnoreResult) == 0)
2113-
TryEmitPrimitiveOrEnumOrDecimalConstant(il, resultObj, exprType);
2114-
return true;
2108+
if ((setup & CompilerFlags.DisableInterpreter) == 0 && exprType.IsPrimitive &&
2109+
Interpreter.TryInterpret(out var resultObj, expr))
2110+
{
2111+
if ((parent & ParentFlags.IgnoreResult) == 0)
2112+
TryEmitPrimitiveOrEnumOrDecimalConstant(il, resultObj, exprType);
2113+
return true;
2114+
}
2115+
return TryEmitArithmetic(((BinaryExpression)expr).Left, ((BinaryExpression)expr).Right, nodeType, exprType, paramExprs, il,
2116+
ref closure, setup, parent);
21152117
}
2116-
return TryEmitArithmetic(((BinaryExpression)expr).Left, ((BinaryExpression)expr).Right, nodeType, exprType, paramExprs, il,
2117-
ref closure, setup, parent);
2118-
21192118
case ExpressionType.Power:
21202119
case ExpressionType.And:
21212120
case ExpressionType.Or:
21222121
case ExpressionType.ExclusiveOr:
21232122
case ExpressionType.LeftShift:
21242123
case ExpressionType.RightShift:
2125-
// todo: @wip #472 add interpretation when those node types are supported
2124+
// todo: @wip @feature #472 add interpretation when those node types are supported
21262125
return TryEmitArithmetic(((BinaryExpression)expr).Left, ((BinaryExpression)expr).Right, nodeType, exprType, paramExprs, il,
21272126
ref closure, setup, parent);
21282127

21292128
case ExpressionType.AndAlso:
21302129
case ExpressionType.OrElse:
2131-
// todo: @wip but where is `.Not` ?
2132-
// todo: @wip interpreter
2133-
return TryEmitLogicalOperator((BinaryExpression)expr, nodeType, paramExprs, il, ref closure, setup, parent);
2134-
2130+
{
2131+
if ((setup & CompilerFlags.DisableInterpreter) == 0 && exprType.IsPrimitive &&
2132+
Interpreter.TryInterpretBoolean(out var boolResult, expr))
2133+
{
2134+
if ((parent & ParentFlags.IgnoreResult) == 0)
2135+
il.Demit(boolResult ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
2136+
return true;
2137+
}
2138+
return TryEmitLogicalOperator((BinaryExpression)expr, nodeType, paramExprs, il, ref closure, setup, parent);
2139+
}
2140+
case ExpressionType.Not:
2141+
{
2142+
if ((setup & CompilerFlags.DisableInterpreter) == 0 && exprType.IsPrimitive &&
2143+
Interpreter.TryInterpretBoolean(out var boolResult, expr))
2144+
{
2145+
if ((parent & ParentFlags.IgnoreResult) == 0)
2146+
il.Demit(boolResult ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
2147+
return true;
2148+
}
2149+
return TryEmitNot((UnaryExpression)expr, paramExprs, il, ref closure, setup, parent);
2150+
}
21352151
case ExpressionType.Coalesce:
21362152
return TryEmitCoalesceOperator((BinaryExpression)expr, paramExprs, il, ref closure, setup, parent);
21372153

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
3+
#if LIGHT_EXPRESSION
4+
using ExpressionType = System.Linq.Expressions.ExpressionType;
5+
using static FastExpressionCompiler.LightExpression.Expression;
6+
namespace FastExpressionCompiler.LightExpression.IssueTests;
7+
#else
8+
using System.Linq.Expressions;
9+
using static System.Linq.Expressions.Expression;
10+
namespace FastExpressionCompiler.IssueTests;
11+
#endif
12+
13+
public struct Issue472_TryInterpret_and_Reduce_primitive_arithmetic_and_logical_expressions_during_the_compilation : ITestX
14+
{
15+
public void Run(TestRun t)
16+
{
17+
Logical_expression_started_with_not(t);
18+
}
19+
20+
public void Logical_expression_started_with_not(TestContext t)
21+
{
22+
var p = Parameter(typeof(bool), "p");
23+
var expr = Lambda<Func<bool, bool>>(
24+
Not(AndAlso(Constant(true), p)),
25+
p);
26+
27+
expr.PrintCSharp();
28+
29+
var fs = expr.CompileSys();
30+
fs.PrintIL();
31+
t.IsTrue(fs(true));
32+
t.IsFalse(fs(false));
33+
34+
var ff = expr.CompileFast(false);
35+
ff.PrintIL();
36+
t.IsTrue(ff(true));
37+
t.IsTrue(ff(false));
38+
}
39+
}

test/FastExpressionCompiler.TestsRunner/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public class Program
1010
public static void Main()
1111
{
1212
var t = new LightExpression.TestRun();
13+
t.Run(new LightExpression.IssueTests.Issue472_TryInterpret_and_Reduce_primitive_arithmetic_and_logical_expressions_during_the_compilation());
1314
t.Run(new LightExpression.IssueTests.Issue468_Optimize_the_delegate_access_to_the_Closure_object_for_the_modern_NET());
1415

1516
// new Issue55_CompileFast_crash_with_ref_parameter().Run();

0 commit comments

Comments
 (0)