Skip to content

Commit cd46984

Browse files
committed
adding debug info to CompileNoArgsNew
1 parent e47acb2 commit cd46984

File tree

2 files changed

+24
-12
lines changed

2 files changed

+24
-12
lines changed

src/FastExpressionCompiler/FastExpressionCompiler.cs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -476,15 +476,18 @@ public static TDelegate TryCompileWithoutClosure<TDelegate>(this LambdaExpressio
476476
return dlg;
477477
}
478478

479-
private static Delegate CompileNoArgsNew(ConstructorInfo ctor, Type delegateType, Type[] closurePlusParamTypes, Type returnType)
479+
private static Delegate CompileNoArgsNew(NewExpression newExpr, Type delegateType, Type[] closurePlusParamTypes, Type returnType, CompilerFlags flags)
480480
{
481481
var method = new DynamicMethod(string.Empty, returnType, closurePlusParamTypes, typeof(ArrayClosure), true);
482482
var il = DynamicMethodHacks.RentPooledOrNewILGenerator(method, returnType, closurePlusParamTypes, newStreamSize: 16);
483-
il.Demit(OpCodes.Newobj, ctor);
483+
il.Demit(OpCodes.Newobj, newExpr.Constructor);
484484
if (returnType == typeof(void))
485485
il.Demit(OpCodes.Pop);
486486
il.Demit(OpCodes.Ret);
487-
var dlg = method.CreateDelegate(delegateType, EmptyArrayClosure);
487+
488+
var hasDebugInfo = (flags & CompilerFlags.EnableDelegateDebugInfo) != 0;
489+
var closure = !hasDebugInfo ? EmptyArrayClosure : new DebugArrayClosure(null, Lambda(newExpr, Tools.Empty<PE>()));
490+
var dlg = method.CreateDelegate(delegateType, closure);
488491
DynamicMethodHacks.FreePooledILGenerator(method, il);
489492
return dlg;
490493
}
@@ -493,12 +496,11 @@ private static Delegate CompileNoArgsNew(ConstructorInfo ctor, Type delegateType
493496
internal static object TryCompileBoundToFirstClosureParam(Type delegateType, Expression bodyExpr, IParameterProvider paramExprs,
494497
Type returnType, CompilerFlags flags)
495498
{
499+
// There is no Return of the pooled parameter types here,
500+
// because in the rarest case with the unused lambda arguments we may just exhaust the pooled instance
496501
var closureAndParamTypes = RentPooledOrNewClosureTypeToParamTypes(paramExprs);
497-
if (bodyExpr is NoArgsNewClassIntrinsicExpression newNoArgs)
498-
{
499-
// there is no Return of the pooled parameter types here, because in the rarest case with the unused lambda arguments we may just exhaust the pooled instance
500-
return CompileNoArgsNew(newNoArgs.Constructor, delegateType, closureAndParamTypes, returnType);
501-
}
502+
if (bodyExpr is NoArgsNewClassIntrinsicExpression newExpr)
503+
return CompileNoArgsNew(newExpr, delegateType, closureAndParamTypes, returnType, flags);
502504
#else
503505
internal static object TryCompileBoundToFirstClosureParam(Type delegateType, Expression bodyExpr, IReadOnlyList<PE> paramExprs,
504506
Type returnType, CompilerFlags flags)
@@ -528,8 +530,8 @@ internal static object TryCompileBoundToFirstClosureParam(Type delegateType, Exp
528530
closure = constantsAndNestedLambdas == null ? EmptyArrayClosure : new ArrayClosure(constantsAndNestedLambdas);
529531
else
530532
{
531-
var debugExpr = Lambda(delegateType, bodyExpr, paramExprs?.ToReadOnlyList() ?? Tools.Empty<PE>());
532-
closure = new DebugArrayClosure(constantsAndNestedLambdas, debugExpr);
533+
var debugLambdaExpr = Lambda(delegateType, bodyExpr, paramExprs?.ToReadOnlyList() ?? Tools.Empty<PE>());
534+
closure = new DebugArrayClosure(constantsAndNestedLambdas, debugLambdaExpr);
533535
}
534536

535537
// note: @slow this is what System.Compiles does and which makes the compilation 10x slower, but the invocation become faster by a single branch instruction
@@ -1822,10 +1824,10 @@ private static bool TryCompileNestedLambda(ref ClosureInfo nestedClosureInfo, Ne
18221824
#if LIGHT_EXPRESSION
18231825
var nestedLambdaParamExprs = (IParameterProvider)nestedLambdaExpr;
18241826

1825-
if (nestedLambdaBody is NoArgsNewClassIntrinsicExpression newNoArgs)
1827+
if (nestedLambdaBody is NoArgsNewClassIntrinsicExpression newExpr)
18261828
{
18271829
var paramTypes = RentPooledOrNewClosureTypeToParamTypes(nestedLambdaParamExprs);
1828-
nestedLambdaInfo.Lambda = CompileNoArgsNew(newNoArgs.Constructor, nestedLambdaExpr.Type, paramTypes, nestedReturnType);
1830+
nestedLambdaInfo.Lambda = CompileNoArgsNew(newExpr, nestedLambdaExpr.Type, paramTypes, nestedReturnType, flags);
18291831
FreePooledClosureTypeAndParamTypes(paramTypes);
18301832
return true;
18311833
}

test/FastExpressionCompiler.LightExpression.UnitTests/NestedLambdasSharedToExpressionCodeStringTest.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,22 @@ public class NestedLambdasSharedToExpressionCodeStringTest : ITest
1010
{
1111
public int Run()
1212
{
13+
Issue478_Debug_info_should_be_included_into_nested_lambdas();
1314
Should_output_a_valid_expression_code();
1415
Test_the_output_expression_code();
1516
return 2;
1617
}
1718

1819

20+
public void Issue478_Debug_info_should_be_included_into_nested_lambdas()
21+
{
22+
var e = CreateExpression();
23+
24+
var f = e.CompileFast(true, CompilerFlags.EnableDelegateDebugInfo);
25+
26+
Asserts.IsNotNull(f);
27+
}
28+
1929
public void Should_output_a_valid_expression_code()
2030
{
2131
var e = CreateExpression();

0 commit comments

Comments
 (0)