Skip to content

Commit

Permalink
fix #449
Browse files Browse the repository at this point in the history
  • Loading branch information
dadhi committed Jan 28, 2025
1 parent 7fde6d7 commit 6b59cd2
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 9 deletions.
13 changes: 8 additions & 5 deletions src/FastExpressionCompiler/FastExpressionCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3753,6 +3753,8 @@ private static bool EmitMemberInit(MemberInitExpression expr, IReadOnlyList<PE>
{
if (!TryEmit(expr.Expression, paramExprs, il, ref closure, setup, parent))
return false;
if (valueVarIndex != -1)
EmitStoreLocalVariable(il, valueVarIndex);
}
else
#endif
Expand Down Expand Up @@ -6648,24 +6650,25 @@ public static void Demit(this ILGenerator il, OpCode opcode, [CallerMemberName]
}

[MethodImpl((MethodImplOptions)256)]
public static void Demit(this ILGenerator il, OpCode opcode, Type value, [CallerMemberName] string emitterName = null, [CallerLineNumber] int emitterLine = 0)
public static void Demit(this ILGenerator il, OpCode opcode, Type type, [CallerMemberName] string emitterName = null, [CallerLineNumber] int emitterLine = 0)
{
il.Emit(opcode, value);
Debug.WriteLine($"{opcode} {value} -- {emitterName}:{emitterLine}");
il.Emit(opcode, type);
Debug.WriteLine($"{opcode} {type.ToCode(stripNamespace: true)} -- {emitterName}:{emitterLine}");
}

[MethodImpl((MethodImplOptions)256)]
public static void Demit(this ILGenerator il, OpCode opcode, FieldInfo value, [CallerMemberName] string emitterName = null, [CallerLineNumber] int emitterLine = 0)
{
il.Emit(opcode, value);
var t = value.DeclaringType;
var fieldStr = value.FieldType.Name + " " + t.Name + "." + value.Name;
var fieldStr = value.FieldType.ToCode(stripNamespace: true) + " " + t.ToCode(stripNamespace: true) + "." + value.Name;
Debug.WriteLine($"{opcode} {fieldStr} -- {emitterName}:{emitterLine}");
}

[MethodImpl((MethodImplOptions)256)]
public static void Demit(this ILGenerator il, OpCode opcode, MethodInfo value, [CallerMemberName] string emitterName = null, [CallerLineNumber] int emitterLine = 0)
{
// todo: @wip output Type same as for FieldInfo
il.Emit(opcode, value);
Debug.WriteLine($"{opcode} {value} -- {emitterName}:{emitterLine}");
}
Expand All @@ -6674,7 +6677,7 @@ public static void Demit(this ILGenerator il, OpCode opcode, MethodInfo value, [
public static void Demit(this ILGenerator il, OpCode opcode, ConstructorInfo value, [CallerMemberName] string emitterName = null, [CallerLineNumber] int emitterLine = 0)
{
il.Emit(opcode, value);
var ctorStr = value.ToString().Replace(".", (value.DeclaringType?.Name ?? "") + ".");
var ctorStr = value.ToString().Replace(".", (value.DeclaringType?.ToCode(stripNamespace: true) ?? "") + ".");
Debug.WriteLine($"{opcode} {ctorStr} -- {emitterName}:{emitterLine}");
}

Expand Down
6 changes: 5 additions & 1 deletion test/FastExpressionCompiler.ILDecoder/ILReaderFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,11 @@ public static StringBuilder ToILString(this MethodInfo method, StringBuilder s =
if (il is InlineFieldInstruction f)
s.Append(' ').AppendTypeName(f.Field.DeclaringType).Append('.').Append(f.Field.Name);
else if (il is InlineMethodInstruction m)
s.Append(' ').AppendTypeName(m.Method.DeclaringType).Append('.').Append(m.Method.Name);
{
s.Append(' ').AppendTypeName(m.Method.DeclaringType);
if (!m.Method.IsConstructor)
s.Append('.').Append(m.Method.Name);
}
else if (il is InlineTypeInstruction t)
s.Append(' ').AppendTypeName(t.Type);
else if (il is InlineTokInstruction tok)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ public class Issue449_MemberInit_produces_InvalidProgram : ITest
{
public int Run()
{
// Original_case();
return 1;
Original_case();
Struct_without_ctor_case();
return 2;
}

public struct SampleType
Expand All @@ -27,6 +28,11 @@ public struct SampleType
public SampleType() { }
}

public struct SampleType_NoCtor
{
public int? Value { get; set; }
}

[Test]
public void Original_case()
{
Expand All @@ -52,4 +58,29 @@ public void Original_case()
var fr = ff();
Assert.AreEqual(666, sr.Value.Value);
}

[Test]
public void Struct_without_ctor_case()
{
var valueProp = typeof(SampleType_NoCtor).GetProperty(nameof(SampleType_NoCtor.Value));

var expr = Lambda<Func<SampleType_NoCtor>>(
MemberInit(
New(typeof(SampleType_NoCtor)),
Bind(valueProp, Constant(666, typeof(int?)))));

expr.PrintCSharp();

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

var sr = fs();
Assert.AreEqual(666, sr.Value.Value);

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

var fr = ff();
Assert.AreEqual(666, sr.Value.Value);
}
}
3 changes: 3 additions & 0 deletions test/FastExpressionCompiler.TestsRunner.Net472/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,9 @@ void Run(Func<int> run, string name = null)
Run(new Issue443_Nested_Calls_with_lambda_parameters().Run);
Run(new LightExpression.IssueTests.Issue443_Nested_Calls_with_lambda_parameters().Run);

Run(new Issue449_MemberInit_produces_InvalidProgram().Run);
Run(new LightExpression.IssueTests.Issue449_MemberInit_produces_InvalidProgram().Run);

Console.WriteLine($"{Environment.NewLine}IssueTests are passing in {sw.ElapsedMilliseconds} ms.");
});

Expand Down
5 changes: 4 additions & 1 deletion test/FastExpressionCompiler.TestsRunner/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class Program
{
public static void Main()
{
new LightExpression.IssueTests.Issue449_MemberInit_produces_InvalidProgram().Run();
// new LightExpression.IssueTests.Issue449_MemberInit_produces_InvalidProgram().Run();

// new LightExpression.IssueTests.Issue437_Shared_variables_with_nested_lambdas_returning_incorrect_values().Run();
// new LightExpression.IssueTests.Issue353_NullReferenceException_when_calling_CompileFast_results().Run();
Expand Down Expand Up @@ -348,6 +348,9 @@ void Run(Func<int> run, string name = null)
Run(new Issue443_Nested_Calls_with_lambda_parameters().Run);
Run(new LightExpression.IssueTests.Issue443_Nested_Calls_with_lambda_parameters().Run);

Run(new Issue449_MemberInit_produces_InvalidProgram().Run);
Run(new LightExpression.IssueTests.Issue449_MemberInit_produces_InvalidProgram().Run);

Console.WriteLine($"{Environment.NewLine}IssueTests are passing in {sw.ElapsedMilliseconds} ms.");
});

Expand Down

0 comments on commit 6b59cd2

Please sign in to comment.