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: 5 additions & 2 deletions src/FastExpressionCompiler/FastExpressionCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -482,8 +482,11 @@ internal static Type[] RentPooledOrNewClosureTypeToParamTypes(ParamExprs paramEx
var count = paramExprs.GetParamCount();
if (count == 0)
return _closureAsASingleParamType;

var pooledOrNew = count < 8 ? Interlocked.Exchange(ref _paramTypesPoolWithElem0OfLength1[count], null) ?? new Type[count + 1] : new Type[count + 1];
// The hidden closure argument also counts toward the CLI signature limit.
// The pooled small-signature path is already below that limit.
var pooledOrNew = count < 8 ? Interlocked.Exchange(ref _paramTypesPoolWithElem0OfLength1[count], null) ?? new Type[count + 1] :
count < ushort.MaxValue ? new Type[count + 1] :
throw new InvalidProgramException("The lambda and its closure exceed the maximum method parameter count.");
pooledOrNew[0] = typeof(ArrayClosure);
for (var i = 0; i < count; i++)
{
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.ExcessiveArityRegressionTests());
t.Run(new LightExpression.UnitTests.NestedStructFieldAddressRegressionTests());
t.Run(new LightExpression.IssueTests.Issue183_NullableDecimal());
t.Run(new LightExpression.IssueTests.Issue398_Optimize_Switch_with_OpCodes_Switch());
Expand All @@ -60,6 +61,7 @@ static void RunLightExpressionTests(object state)
var fecTestsStopwatch = Stopwatch.StartNew();

var fecTests = new TestRun();
fecTests.Run(new ExcessiveArityRegressionTests());
fecTests.Run(new NestedStructFieldAddressRegressionTests());
fecTests.Run(new Issue183_NullableDecimal());
fecTests.Run(new Issue468_Optimize_the_delegate_access_to_the_Closure_object_for_the_modern_NET());
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.ExcessiveArityRegressionTests());
#if NET8_0_OR_GREATER
lt.Run(new LightExpression.UnitTests.NestedStructFieldAddressRegressionTests());
lt.Run(new LightExpression.IssueTests.Issue490_Regression_in_compiling_lambdas_with_ref_struct_parameters());
Expand All @@ -86,6 +87,7 @@ public static void Main(string[] args)
});

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

public struct ExcessiveArityRegressionTests : ITestX
{
public void Run(TestRun t)
{
Unrepresentable_method_signatures_are_rejected_during_compilation(t);
Large_supported_signatures_keep_argument_indices(t);
}

public void Unrepresentable_method_signatures_are_rejected_during_compilation(TestContext t)
{
var parameters = Enumerable.Range(0, ushort.MaxValue).Select(_ => S.Parameter(typeof(int))).ToArray();
var system = S.Lambda(parameters[parameters.Length - 1], parameters);
var expression = system.FromSysExpression();
t.Throws<InvalidProgramException>(() => expression.CompileFast(true));
t.Throws<InvalidProgramException>(() => expression.CompileFast(true, CompilerFlags.ThrowOnNotSupportedExpression));
t.Throws<InvalidProgramException>(() => system.Compile());
}

public void Large_supported_signatures_keep_argument_indices(TestContext t)
{
foreach (var count in new[] { 255, 256, 300 })
{
var parameters = Enumerable.Range(0, count).Select(_ => S.Parameter(typeof(int))).ToArray();
var system = S.Lambda(S.Add(parameters[0], parameters[count - 1]), parameters);
var fast = system.FromSysExpression().CompileFast(true);
if (!t.IsNotNull(fast)) return;
var arguments = Enumerable.Range(0, count).Select(i => (object)i).ToArray();
t.AreEqual(count - 1, fast.DynamicInvoke(arguments));
t.AreEqual(system.Compile().DynamicInvoke(arguments), fast.DynamicInvoke(arguments));
}
}
}
Loading