@@ -2107,7 +2107,7 @@ public static bool TryEmit(Expression expr,
21072107 case ExpressionType.AndAlso:
21082108 case ExpressionType.OrElse:
21092109 {
2110- if (exprType.IsPrimitive && Interpreter.TryInterpretBool_new(out var resultBool, expr, setup))
2110+ if (Interpreter.TryInterpretBool_new(out var resultBool, expr, setup))
21112111 {
21122112 if ((parent & ParentFlags.IgnoreResult) == 0)
21132113 il.Demit(resultBool ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
@@ -2117,7 +2117,7 @@ public static bool TryEmit(Expression expr,
21172117 }
21182118 case ExpressionType.Not:
21192119 {
2120- if (exprType.IsPrimitive && Interpreter.TryInterpretBool_new(out var resultBool, expr, setup))
2120+ if (Interpreter.TryInterpretBool_new(out var resultBool, expr, setup))
21212121 {
21222122 if ((parent & ParentFlags.IgnoreResult) == 0)
21232123 il.Demit(resultBool ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
@@ -2130,7 +2130,13 @@ public static bool TryEmit(Expression expr,
21302130
21312131 case ExpressionType.Conditional:
21322132 var condExpr = (ConditionalExpression)expr;
2133- return TryEmitConditional(condExpr.Test, condExpr.IfTrue, condExpr.IfFalse, paramExprs, il, ref closure, setup, parent);
2133+ var testExpr = condExpr.Test;
2134+ if (Interpreter.TryInterpretBool_new(out var testIsTrue, testExpr, setup))
2135+ {
2136+ expr = testIsTrue ? condExpr.IfTrue : condExpr.IfFalse;
2137+ continue; // no recursion, just continue with the left or right side of condition
2138+ }
2139+ return TryEmitConditional(testExpr, condExpr.IfTrue, condExpr.IfFalse, paramExprs, il, ref closure, setup, parent);
21342140
21352141 case ExpressionType.PostIncrementAssign:
21362142 case ExpressionType.PreIncrementAssign:
@@ -5256,9 +5262,17 @@ private static bool TryEmitSwitch(SwitchExpression expr, IReadOnlyList<PE> param
52565262 var cs0 = cases[0];
52575263 if (cs0.TestValues.Count == 1)
52585264 {
5259- Expression testExpr = customEqualMethod == null
5260- ? Equal(switchValueExpr, cs0.TestValues[0])
5261- : Call(customEqualMethod, switchValueExpr, cs0.TestValues[0]);
5265+ Expression testExpr;
5266+ if (customEqualMethod == null)
5267+ {
5268+ // todo: @perf avoid creation of the additional expression
5269+ testExpr = Equal(switchValueExpr, cs0.TestValues[0]);
5270+ if (Interpreter.TryInterpretBool_new(out var testResult, testExpr, setup))
5271+ return TryEmit(testResult ? cs0.Body : expr.DefaultBody, paramExprs, il, ref closure, setup, parent);
5272+ }
5273+ else
5274+ testExpr = Call(customEqualMethod, switchValueExpr, cs0.TestValues[0]);
5275+
52625276 return TryEmitConditional(testExpr, cs0.Body, expr.DefaultBody, paramExprs, il, ref closure, setup, parent);
52635277 }
52645278 }
@@ -5944,12 +5958,6 @@ private static bool TryEmitConditional(
59445958#endif
59455959 ILGenerator il, ref ClosureInfo closure, CompilerFlags setup, ParentFlags parent)
59465960 {
5947- // Try emit a single side of the condition based on the interpreted condition value
5948- if (Interpreter.TryInterpretBool_new(out var testIsTrue, testExpr, setup))
5949- return testIsTrue
5950- ? TryEmit(ifTrueExpr, paramExprs, il, ref closure, setup, parent)
5951- : TryEmit(ifFalseExpr, paramExprs, il, ref closure, setup, parent);
5952-
59535961 testExpr = TryReduceCondition(testExpr);
59545962 var testNodeType = testExpr.NodeType;
59555963
@@ -7961,6 +7969,7 @@ internal static bool TryInterpretPrimitive(ref UValue value, Expression expr)
79617969 return false;
79627970 }
79637971
7972+ // todo: @perf try split to `TryInterpretBinary` overload to streamline the calls for TryEmitConditional and similar
79647973 /// <summary>Tries to interpret the expression of the Primitive type of Constant, Convert, Logical, Comparison, Arithmetic.</summary>
79657974 internal static bool TryInterpretBool(ref bool resultBool, Expression expr, ExpressionType nodeType)
79667975 {
0 commit comments