Skip to content

Commit

Permalink
fix the LambdaVarIndex type to the NestedLambdaForNonPassedParams
Browse files Browse the repository at this point in the history
  • Loading branch information
dadhi committed Dec 19, 2024
1 parent 4fac73c commit 7371913
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 18 deletions.
20 changes: 10 additions & 10 deletions src/FastExpressionCompiler/FastExpressionCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -605,9 +605,6 @@ public sealed class NestedLambdaInfo

public NestedLambdaInfo(LambdaExpression lambdaExpression) => LambdaExpression = lambdaExpression;

/// <summary>Returns the type of lambda</summary>
public Type GetLambdaType() => (Lambda is NestedLambdaForNonPassedParams n ? n.NestedLambda : Lambda).GetType();

/// <summary>Compares 2 lambda expressions for equality</summary>
public bool HasTheSameLambdaExpression(LambdaExpression lambda) => // todo: @unclear parameters or is comparing the body is enough?
ReferenceEquals(LambdaExpression, lambda) ||
Expand Down Expand Up @@ -3541,9 +3538,11 @@ internal static void EmitLoadConstantsAndNestedLambdasIntoVars(ILGenerator il, r
// Load constants array field from Closure and store it into the variable
il.Demit(OpCodes.Ldarg_0);
il.Demit(OpCodes.Ldfld, ArrayClosureArrayField);
EmitStoreLocalVariable(il, il.GetNextLocalVarIndex(typeof(object[]))); // always does Stloc_0
// important that the constant will contain the nested lambdas as well in the same array after the actual constants, so the Count indicates where the constants end
var constItems = closure.Constants.Items; // todo: @perf why do we getting when non constants is stored but just a nested lambda is present?
EmitStoreLocalVariable(il, il.GetNextLocalVarIndex(typeof(object[]))); // always does Stloc_0, because it is done at start of the lambda emit

// important that the constant will contain the nested lambdas as well in the same array after the actual constants,
// so the Count indicates where the constants end
var constItems = closure.Constants.Items;
var constCount = closure.Constants.Count;

short varIndex;
Expand Down Expand Up @@ -3571,7 +3570,7 @@ internal static void EmitLoadConstantsAndNestedLambdasIntoVars(ILGenerator il, r
{
var lambdaInfo = nestedLambdas[i];
EmitLoadClosureArrayItem(il, constCount + i);
lambdaInfo.LambdaVarIndex = varIndex = (short)il.GetNextLocalVarIndex(lambdaInfo.GetLambdaType());
lambdaInfo.LambdaVarIndex = varIndex = (short)il.GetNextLocalVarIndex(lambdaInfo.Lambda.GetType());
EmitStoreLocalVariable(il, varIndex);
}
}
Expand Down Expand Up @@ -4986,8 +4985,7 @@ private static bool TryEmitNestedLambda(LambdaExpression lambdaExpr, IReadOnlyLi
il.Demit(OpCodes.Ldfld, NestedLambdaForNonPassedParams.NestedLambdaField);

// Load the nonPassedParams as a first argument of closure
EmitLoadLocalVariable(il, nestedLambdaInfo.LambdaVarIndex);
il.Demit(OpCodes.Ldfld, NestedLambdaForNonPassedParams.NonPassedParamsField);
EmitLoadLocalVariable(il, nonPassedParamsVarIndex);

// Load the constants as a second argument and call the closure constructor
if (nestedLambdaInfo.Lambda is NestedLambdaForNonPassedParamsWithConstants)
Expand All @@ -5000,7 +4998,9 @@ private static bool TryEmitNestedLambda(LambdaExpression lambdaExpr, IReadOnlyLi
il.Demit(OpCodes.Newobj, ArrayClosureWithNonPassedParamsCtor);

// Call the `Curry` method with the nested lambda and closure to produce a closed lambda with the expected signature
var lambdaTypeArgs = nestedLambdaInfo.GetLambdaType().GetGenericArguments();
var lambda = nestedLambdaInfo.Lambda;
var lambdaType = (lambda is NestedLambdaForNonPassedParams lp ? lp.NestedLambda : lambda).GetType();
var lambdaTypeArgs = lambdaType.GetGenericArguments();
var nestedLambdaExpr = nestedLambdaInfo.LambdaExpression;
var closureMethod = nestedLambdaExpr.ReturnType == typeof(void)
? CurryClosureActions.Methods[lambdaTypeArgs.Length - 1].MakeGenericMethod(lambdaTypeArgs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ public class Issue437_Shared_variables_with_nested_lambdas_returning_incorrect_v
{
public int Run()
{
Simplified_test();
Simplified_test_no_inlining();
Simplified_test();

// Nested_lambda_with_shared_variable_Workaround_with_struct();
Nested_lambda_with_shared_variable_Workaround_with_struct();
Nested_lambda_with_shared_variable();
Nested_lambda_with_shared_variable_Workaround();
return 2;
Expand Down Expand Up @@ -48,9 +48,6 @@ public void Simplified_test()
var ff = expr.CompileFast(false);
ff.PrintIL();

if (ff.TryGetDebugClosureNestedLambda(0, out var nested))
nested.PrintIL("nested");

var fr = ff();
Assert.AreEqual(3, fr);
}
Expand Down Expand Up @@ -79,9 +76,6 @@ public void Simplified_test_no_inlining()
var ff = expr.CompileFast(false, CompilerFlags.NoInvocationLambdaInlining);
ff.PrintIL();

// if (ff.TryGetDebugClosureNestedLambda(0, out var nested))
// nested.PrintIL("nested");

var fr = ff();
Assert.AreEqual(3, fr);
}
Expand Down

0 comments on commit 7371913

Please sign in to comment.