Skip to content
Open
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
12 changes: 4 additions & 8 deletions src/FastExpressionCompiler/FastExpressionCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4703,17 +4703,13 @@ private static bool EmitMemberInit(MemberInitExpression expr, ILGenerator il, re
var argCount = argExprs.GetArgCount();
if (argCount > 0)
{
var args = newExpr.Constructor.GetParameters();
for (var i = 0; i < argCount; i++)
if (!TryEmit(argExprs.GetArgument(i), il, ref context, parent, args[i].ParameterType.IsByRef ? i : -1))
return false;
if (!TryEmitNew(newExpr, il, ref context, ParentFlags.CtorCall)) return false;
if (valueVarIndex != -1) EmitStoreLocalVariable(il, valueVarIndex);
}

if (newExpr.Constructor != null)
else if (newExpr.Constructor != null)
{
il.Demit(OpCodes.Newobj, newExpr.Constructor);
if (valueVarIndex != -1)
EmitStoreLocalVariable(il, valueVarIndex);
if (valueVarIndex != -1) EmitStoreLocalVariable(il, valueVarIndex);
}
else if (valueVarIndex != -1)
InitValueTypeVariable(il, exprType, valueVarIndex);
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 @@ -78,6 +78,7 @@ static void RunLightExpressionTests(object state)
t.Run(new LightExpression.UnitTests.ByRefConversionRegressionTests());
t.Run(new LightExpression.UnitTests.PropertyGetterReceiverRegressionTests());
t.Run(new LightExpression.UnitTests.RuntimeTypeConstantRegressionTests());
t.Run(new LightExpression.UnitTests.MemberConstructorExceptionTests());
t.Run(new LightExpression.UnitTests.MethodBasedNotRegressionTests());
t.Run(new LightExpression.UnitTests.ExtensionReductionIdentityRegressionTests());
t.Run(new LightExpression.UnitTests.LiftedOperandEvaluationRegressionTests());
Expand Down Expand Up @@ -138,6 +139,7 @@ static void RunLightExpressionTests(object state)
fecTests.Run(new ByRefConversionRegressionTests());
fecTests.Run(new PropertyGetterReceiverRegressionTests());
fecTests.Run(new RuntimeTypeConstantRegressionTests());
fecTests.Run(new MemberConstructorExceptionTests());
fecTests.Run(new MethodBasedNotRegressionTests());
fecTests.Run(new CustomReducibleNodeRegressionTests());
fecTests.Run(new ExtensionReductionIdentityRegressionTests());
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 @@ -110,6 +110,7 @@ public static void Main(string[] args)
lt.Run(new LightExpression.UnitTests.ByRefConversionRegressionTests());
lt.Run(new LightExpression.UnitTests.PropertyGetterReceiverRegressionTests());
lt.Run(new LightExpression.UnitTests.RuntimeTypeConstantRegressionTests());
lt.Run(new LightExpression.UnitTests.MemberConstructorExceptionTests());
lt.Run(new LightExpression.UnitTests.MethodBasedNotRegressionTests());
lt.Run(new LightExpression.UnitTests.ExtensionReductionIdentityRegressionTests());
lt.Run(new LightExpression.UnitTests.LiftedOperandEvaluationRegressionTests());
Expand Down Expand Up @@ -157,6 +158,7 @@ public static void Main(string[] args)
st.Run(new ByRefConversionRegressionTests());
st.Run(new PropertyGetterReceiverRegressionTests());
st.Run(new RuntimeTypeConstantRegressionTests());
st.Run(new MemberConstructorExceptionTests());
st.Run(new MethodBasedNotRegressionTests());
st.Run(new CustomReducibleNodeRegressionTests());
st.Run(new ExtensionReductionIdentityRegressionTests());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using S = System.Linq.Expressions.Expression;
#if LIGHT_EXPRESSION
using E = FastExpressionCompiler.LightExpression.Expression;
namespace FastExpressionCompiler.LightExpression.UnitTests;
#else
using E = System.Linq.Expressions.Expression;
namespace FastExpressionCompiler.UnitTests;
#endif
public struct MemberConstructorExceptionTests : ITestX
{
public static List<int> Trace=new List<int>();
public sealed class Model {public int Total;public int Value;public Model(int a,int b){Trace.Add(5);Total=a+b;}}
public struct ValueModel {public int Total;public int Value;public ValueModel(int a,int b){Trace.Add(5);Total=a+b;Value=0;}}
public static int Mark(int n){Trace.Add(n);return n;}
public void Run(TestRun t) { Constructor_arguments_keep_order_before_bindings(t); }
public void Constructor_arguments_keep_order_before_bindings(TestContext t) {
foreach(var type in new[]{typeof(Model),typeof(ValueModel)}) {
var mark=typeof(MemberConstructorExceptionTests).GetMethod(nameof(Mark));
var created=E.New(type.GetConstructor(new[]{typeof(int),typeof(int)}),E.Call(mark,E.Constant(1)),E.TryFinally(E.Call(mark,E.Constant(2)),E.Block(E.Call(mark,E.Constant(3)),E.Empty())));
var tree=E.Lambda<Func<object>>(E.Convert(E.MemberInit(created,E.Bind(type.GetField("Value"),E.Call(mark,E.Constant(4)))),typeof(object)));
#if NETFRAMEWORK
// Framework's System compiler rejects EH inside struct member initializers.
Func<object> system=type.IsValueType?FrameworkValue:(Func<object>)tree.CompileSys();
#else
var system=(Func<object>)tree.CompileSys();
#endif
Trace.Clear();var expected=system();var effects=string.Join(",",Trace);
foreach(var flags in new[]{CompilerFlags.Default,CompilerFlags.NoInvocationLambdaInlining,CompilerFlags.EnableDelegateDebugInfo}) {var fast=tree.CompileFast(true,flags);if(!t.IsNotNull(fast))return;Trace.Clear();var actual=fast();t.AreEqual(type.GetField("Total").GetValue(expected),type.GetField("Total").GetValue(actual));t.AreEqual(type.GetField("Value").GetValue(expected),type.GetField("Value").GetValue(actual));t.AreEqual(effects,string.Join(",",Trace));}
}
}
#if NETFRAMEWORK
private static object FrameworkValue() {
var first=Mark(1);int second;
try{second=Mark(2);}finally{Mark(3);}
var result=new ValueModel(first,second);result.Value=Mark(4);return result;
}
#endif

}
Loading