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
27 changes: 19 additions & 8 deletions src/FastExpressionCompiler/FastExpressionCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2430,7 +2430,7 @@ private static bool TryEmitNew(Expression expr, IReadOnlyList<PE> paramExprs, IL
CompilerFlags setup, ParentFlags parent)
#endif
{
parent |= ParentFlags.CtorCall;
var flags = ParentFlags.CtorCall;
var newExpr = (NewExpression)expr;
#if SUPPORTS_ARGUMENT_PROVIDER
var argExprs = (IArgumentProvider)newExpr;
Expand All @@ -2449,15 +2449,15 @@ private static bool TryEmitNew(Expression expr, IReadOnlyList<PE> paramExprs, IL
// see the #488 for the details.
if (argCount == 1)
{
if (!TryEmit(argExprs.GetArgument(0), paramExprs, il, ref closure, setup, parent, pars[0].ParameterType.IsByRef ? 0 : -1))
if (!TryEmit(argExprs.GetArgument(0), paramExprs, il, ref closure, setup, flags, pars[0].ParameterType.IsByRef ? 0 : -1))
return false;
}
else
{
if (!closure.ArgsContainingComplexExpression.Map.ContainsKey(newExpr))
{
for (var i = 0; i < argCount; ++i)
if (!TryEmit(argExprs.GetArgument(i), paramExprs, il, ref closure, setup, parent, pars[i].ParameterType.IsByRef ? i : -1))
if (!TryEmit(argExprs.GetArgument(i), paramExprs, il, ref closure, setup, flags, pars[i].ParameterType.IsByRef ? i : -1))
return false;
}
else
Expand All @@ -2467,7 +2467,7 @@ private static bool TryEmitNew(Expression expr, IReadOnlyList<PE> paramExprs, IL
{
var argExpr = argExprs.GetArgument(i);
var parType = pars[i].ParameterType;
if (!TryEmit(argExpr, paramExprs, il, ref closure, setup, parent, parType.IsByRef ? i : -1))
if (!TryEmit(argExpr, paramExprs, il, ref closure, setup, flags, parType.IsByRef ? i : -1))
return false;
argVars.Add(EmitStoreLocalVariable(il, parType));
}
Expand All @@ -2476,21 +2476,32 @@ private static bool TryEmitNew(Expression expr, IReadOnlyList<PE> paramExprs, IL
}
}
}
var newType = newExpr.Type;
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
if (ctor != null)
il.Demit(OpCodes.Newobj, ctor);
else if (newExpr.Type.IsValueType)
else if (newType.IsValueType)
{
ctor = newExpr.Type.GetConstructor(
ctor = newType.GetConstructor(
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
default, CallingConventions.Any, Tools.Empty<Type>(), default);
if (ctor != null)
il.Demit(OpCodes.Newobj, ctor);
else
EmitLoadLocalVariable(il, InitValueTypeVariable(il, newExpr.Type));
EmitLoadLocalVariable(il, InitValueTypeVariable(il, newType));
}
else
return false;

closure.LastEmitIsAddress = newType.IsValueType && (parent & ParentFlags.InstanceAccess) != 0 && !parent.IgnoresResult();
if (closure.LastEmitIsAddress)
{
EmitStoreAndLoadLocalVariableAddress(il, newType);
}

if (parent.IgnoresResult())
il.Demit(OpCodes.Pop);

return true;
}

Expand Down Expand Up @@ -5081,7 +5092,7 @@ public static bool TryEmitMemberGet(MemberExpression expr,
// if the field is not used as an index, #302
// or if the field is not accessed from the just constructed object `new Widget().DodgyValue`, #333
if (((parent & ParentFlags.InstanceAccess) != 0 &
(parent & (ParentFlags.IndexAccess | ParentFlags.Ctor)) == 0) && field.FieldType.IsValueType)
(parent & ParentFlags.IndexAccess) == 0) && field.FieldType.IsValueType)
isByAddress = true;

// we don't need to duplicate the instance if we are working with the field address to save to it directly,
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 @@ -98,6 +98,8 @@ void Run(Func<int> run, string name = null)
Run(new LightExpression.UnitTests.ConvertOperatorsTests().Run);
Run(new DefaultTests().Run);
Run(new LightExpression.UnitTests.DefaultTests().Run);
Run(new ConstructorCallTests().Run);
Run(new LightExpression.UnitTests.ConstructorCallTests().Run);
Run(new EqualityOperatorsTests().Run);
Run(new LightExpression.UnitTests.EqualityOperatorsTests().Run);
Run(new GotoTests().Run);
Expand Down
Loading