Skip to content

Commit

Permalink
added test for #443
Browse files Browse the repository at this point in the history
  • Loading branch information
dadhi committed Dec 18, 2024
1 parent b2df04d commit c1bb71b
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 14 deletions.
11 changes: 6 additions & 5 deletions src/FastExpressionCompiler/FastExpressionCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1738,14 +1738,15 @@ private static bool TryCompileNestedLambda(ref ClosureInfo nestedClosureInfo, Ne
return false;
il.Demit(OpCodes.Ret);

// If we don't have closure then create a static or an open delegate to pass closure later with `TryEmitNestedLambda`,
// constructing the new closure with non-passed arguments and the rest of items
nestedLambdaInfo.Lambda = nestedLambdaClosure != null
// If we don't have closure then create a static or an open delegate to pass closure later in `TryEmitNestedLambda`,
// constructing the new closure with NonPassedParams and the rest of items stored in NestedLambdaWithConstantsAndNestedLambdas
var nestedLambda = nestedLambdaClosure != null
? method.CreateDelegate(nestedLambdaExpr.Type, nestedLambdaClosure)
: method.CreateDelegate(Tools.GetFuncOrActionType(closurePlusParamTypes, nestedReturnType), null);

if (nestedConstsAndLambdas != null & containsConstantsOrNestedLambdas & hasNonPassedParameters)
nestedLambdaInfo.Lambda = new NestedLambdaWithConstantsAndNestedLambdas(nestedLambdaInfo.Lambda, nestedConstsAndLambdas);
nestedLambdaInfo.Lambda = nestedConstsAndLambdas != null & hasNonPassedParameters
? new NestedLambdaWithConstantsAndNestedLambdas(nestedLambda, nestedConstsAndLambdas)
: nestedLambda;

ReturnClosureTypeToParamTypesToPool(closurePlusParamTypes);
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ public class Issue443_Nested_Calls_with_lambda_parameters : ITest
{
public int Run()
{
Original_case_1();
return 1;
// Original_case();
// Case_with_Invoke();
Case_with_Invoke_NoInlining();
return 2;
}

public class TestClass
Expand All @@ -27,7 +29,7 @@ public class TestClass
}

[Test]
public void Original_case_1()
public void Original_case()
{
var executeDelegate = typeof(TestClass).GetMethod(nameof(TestClass.ExecuteDelegate));
var local = Variable(typeof(int), "local");
Expand All @@ -37,10 +39,6 @@ public void Original_case_1()
Block(
new ParameterExpression[] { local },
Assign(local, Constant(42)),

// Invoke works
//Invoke( Lambda<Func<int>>( local ) )

// Call does not work
Call(executeDelegate, Lambda<Func<int>>(local))
)
Expand All @@ -64,4 +62,76 @@ public void Original_case_1()
var fr = ff();
Assert.AreEqual(42, fr);
}

[Test]
public void Case_with_Invoke()
{
var executeDelegate = typeof(TestClass).GetMethod(nameof(TestClass.ExecuteDelegate));
var local = Variable(typeof(int), "local");

var innerLambda =
Lambda<Func<int>>(
Block(
new ParameterExpression[] { local },
Assign(local, Constant(42)),

// Invoke works
Invoke(Lambda<Func<int>>(local))
)
);

var expr = Lambda<Func<int>>(
Call(executeDelegate, innerLambda)
);

expr.PrintCSharp();

var fs = expr.CompileSys();
fs.PrintIL();

var sr = fs();
Assert.AreEqual(42, sr);

var ff = expr.CompileFast(false);
ff.PrintIL();

var fr = ff();
Assert.AreEqual(42, fr);
}

[Test]
public void Case_with_Invoke_NoInlining()
{
var executeDelegate = typeof(TestClass).GetMethod(nameof(TestClass.ExecuteDelegate));
var local = Variable(typeof(int), "local");

var innerLambda =
Lambda<Func<int>>(
Block(
new ParameterExpression[] { local },
Assign(local, Constant(42)),

// Invoke works
Invoke(Lambda<Func<int>>(local))
)
);

var expr = Lambda<Func<int>>(
Call(executeDelegate, innerLambda)
);

expr.PrintCSharp();

var fs = expr.CompileSys();
fs.PrintIL();

var sr = fs();
Assert.AreEqual(42, sr);

var ff = expr.CompileFast(false, CompilerFlags.NoInvocationLambdaInlining);
ff.PrintIL();

var fr = ff();
Assert.AreEqual(42, fr);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<IsTestProject>false</IsTestProject>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>

<NoWarn>$(NoWarn);NETSDK1005;NETSDK1138;NU1702</NoWarn>
<NoWarn>$(NoWarn);NETSDK1005;NETSDK1138;NU1702;NU1900</NoWarn>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\FastExpressionCompiler.UnitTests\FastExpressionCompiler.UnitTests.csproj" />
Expand Down
3 changes: 2 additions & 1 deletion test/FastExpressionCompiler.TestsRunner/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ public class Program
{
public static void Main()
{
new LightExpression.IssueTests.Issue437_Shared_variables_with_nested_lambdas_returning_incorrect_values().Run();
new LightExpression.IssueTests.Issue443_Nested_Calls_with_lambda_parameters().Run();
// new LightExpression.IssueTests.Issue437_Shared_variables_with_nested_lambdas_returning_incorrect_values().Run();
// new LightExpression.UnitTests.ArithmeticOperationsTests().Run();

RunAllTests();
Expand Down

0 comments on commit c1bb71b

Please sign in to comment.