Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/FastExpressionCompiler/FastExpressionCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6100,8 +6100,7 @@ private static bool TryEmitSwitch(SwitchExpression expr, ILGenerator il, ref Com
var testValExpr = testValues[v];
if (testValExpr is not ConstantExpression && testValExpr is not DefaultExpression)
{
Debug.Assert(false, $"Not supported non-constant,non-default switch case value expression: `{testValExpr}`");
return false;
goto OrderedDispatch;
}
var testValueLong = testValExpr is ConstantExpression constExpr ? ConvertValueObjectToLong(constExpr.Value) : 0L;

Expand Down Expand Up @@ -6351,6 +6350,7 @@ private static bool TryEmitSwitch(SwitchExpression expr, ILGenerator il, ref Com
}
}

OrderedDispatch:
var switchValueIsNullable = switchValueType.IsNullable();
Type switchNullableUnderlyingValueType = null;
MethodInfo switchNullableHasValueMethod = null;
Expand Down Expand Up @@ -8690,7 +8690,8 @@ public static bool TryFindSwitchBranch(SwitchExpression switchExpr, CompilerFlag
var testValues = cases[i].TestValues;
for (var j = 0; j < testValues.Count; j++)
{
if (testValues[j] is not ConstantExpression testConst || testConst.Value == null) continue;
if (testValues[j] is not ConstantExpression testConst) return false;
if (testConst.Value == null) continue;
if (switchValLong == ConvertValueObjectToLong(testConst.Value)) { matchedBody = cases[i].Body; return true; }
}
}
Expand Down
2 changes: 2 additions & 0 deletions test/FastExpressionCompiler.TestsRunner.Net472/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ static void RunLightExpressionTests(object state)
var justLightTestsStopwatch = Stopwatch.StartNew();

var t = (LightExpression.TestRun)state;
t.Run(new LightExpression.UnitTests.RuntimeSwitchCaseRegressionTests());
t.Run(new LightExpression.UnitTests.StaticFieldAddressRegressionTests());
t.Run(new LightExpression.UnitTests.MultidimensionalGetStorageRegressionTests());
t.Run(new LightExpression.UnitTests.AbstractConstructorRegressionTests());
Expand Down Expand Up @@ -78,6 +79,7 @@ static void RunLightExpressionTests(object state)
var fecTestsStopwatch = Stopwatch.StartNew();

var fecTests = new TestRun();
fecTests.Run(new RuntimeSwitchCaseRegressionTests());
fecTests.Run(new StaticFieldAddressRegressionTests());
fecTests.Run(new MultidimensionalGetStorageRegressionTests());
fecTests.Run(new AbstractConstructorRegressionTests());
Expand Down
2 changes: 2 additions & 0 deletions test/FastExpressionCompiler.TestsRunner/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public static void Main(string[] args)
var ltTask = Task.Run(() =>
{
var ltStopwatch = Stopwatch.StartNew();
lt.Run(new LightExpression.UnitTests.RuntimeSwitchCaseRegressionTests());
lt.Run(new LightExpression.UnitTests.StaticFieldAddressRegressionTests());
lt.Run(new LightExpression.UnitTests.MultidimensionalGetStorageRegressionTests());
lt.Run(new LightExpression.UnitTests.AbstractConstructorRegressionTests());
Expand Down Expand Up @@ -104,6 +105,7 @@ public static void Main(string[] args)
});

var stStopwatch = Stopwatch.StartNew();
st.Run(new RuntimeSwitchCaseRegressionTests());
st.Run(new StaticFieldAddressRegressionTests());
st.Run(new MultidimensionalGetStorageRegressionTests());
st.Run(new AbstractConstructorRegressionTests());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using S = System.Linq.Expressions.Expression;
#if LIGHT_EXPRESSION
namespace FastExpressionCompiler.LightExpression.UnitTests;
#else
namespace FastExpressionCompiler.UnitTests;
#endif

public struct RuntimeSwitchCaseRegressionTests : ITestX
{
public void Run(TestRun t) { Numeric_runtime_case_values_are_supported(t); Constant_input_does_not_skip_runtime_tests(t); }
public void Numeric_runtime_case_values_are_supported(TestContext t)
{
var value = S.Parameter(typeof(int)); var test = S.Parameter(typeof(int));
var tree = S.Lambda<Func<int, int, int>>(S.Switch(value, S.Constant(-1), S.SwitchCase(S.Constant(7), S.Add(test, S.Constant(1)))), value, test);
var system = tree.Compile(); var fast = tree.FromSysExpression().CompileFast(true);
if (!t.IsNotNull(fast)) return;
foreach (var x in new[] { int.MinValue, -1, 0, 42, int.MaxValue })
foreach (var y in new[] { -1, 0, 41, int.MaxValue }) t.AreEqual(system(x, y), fast(x, y));
}
public static int Calls;
public static int Test() { ++Calls; return 42; }
public void Constant_input_does_not_skip_runtime_tests(TestContext t)
{
var tree = S.Lambda<Func<int>>(S.Switch(S.Constant(42), S.Constant(-1),
S.SwitchCase(S.Constant(7), S.Call(typeof(RuntimeSwitchCaseRegressionTests).GetMethod(nameof(Test)))),
S.SwitchCase(S.Constant(9), S.Constant(42))));
var fast = tree.FromSysExpression().CompileFast(true);
if (!t.IsNotNull(fast)) return;
Calls = 0; t.AreEqual(7, fast()); t.AreEqual(1, Calls);
}
}
Loading