Skip to content

Commit

Permalink
fixes assignment to ref storage (#259)
Browse files Browse the repository at this point in the history
  • Loading branch information
adrianoc committed Jan 29, 2024
1 parent c05185d commit 247c75c
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 3 deletions.
45 changes: 45 additions & 0 deletions Cecilifier.Core.Tests/Tests/Unit/Miscellaneous.Assingment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System.Collections.Generic;
using NUnit.Framework;

namespace Cecilifier.Core.Tests.Tests.Unit
{
[TestFixture]
public class MiscellaneousAssignmentsTests : CecilifierUnitTestBase
{
[TestCaseSource(nameof(TestScenarios))]
public void TestIndirectLoad_Issue259(string typeName, string expectedLoadOpcode, bool initializeVariable)
{
var code = $$"""
struct S {}
class Foo { {{typeName}} Bar(ref {{typeName}} p) { {{typeName}} local{{ (initializeVariable ? "" : "; local") }} = p; return local; } }
""";

var expectedSnippet = @".*(?<emit>.+\.Emit\(OpCodes\.)Ldarg_1\);\s"
+ $@"\1{expectedLoadOpcode}.+;\s"
+ @"\1Stloc, l_local_\d+\);\s";

var result = RunCecilifier(code);
Assert.That(result.GeneratedCode.ReadToEnd(), Does.Match(expectedSnippet));
}

static IEnumerable<TestCaseData> TestScenarios()
{
foreach(var initializeMode in new[] { true, false } )
{
yield return new TestCaseData("int", "Ldind_I4", initializeMode);
yield return new TestCaseData("long", "Ldind_I8", initializeMode);
yield return new TestCaseData("short", "Ldind_I2", initializeMode);
yield return new TestCaseData("byte", "Ldind_U1", initializeMode);
yield return new TestCaseData("float", "Ldind_R4", initializeMode);
yield return new TestCaseData("double", "Ldind_R8", initializeMode);
yield return new TestCaseData("bool", "Ldind_U1", initializeMode);
yield return new TestCaseData("char", "Ldind_U2", initializeMode);
yield return new TestCaseData("int[]", "Ldind_Ref", initializeMode);
yield return new TestCaseData("System.DateTime", "Ldobj", initializeMode);
yield return new TestCaseData("S", "Ldobj", initializeMode);
}
}

public record struct TestScenario(string TypeName, string ExpectedLoadOpcode, bool VariableInitializer);
}
}
5 changes: 2 additions & 3 deletions Cecilifier.Core/Extensions/ISymbolExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,8 @@ public static OpCode LoadIndirectOpCodeFor(this ITypeSymbol type)
SpecialType.System_Char => OpCodes.Ldind_U2,
SpecialType.System_Boolean => OpCodes.Ldind_U1,
SpecialType.System_Object => OpCodes.Ldind_Ref,
SpecialType.None => OpCodes.Ldind_Ref,

_ => throw new ArgumentException($"Literal type {type} not supported.", nameof(type))

_ => type.IsValueType ? OpCodes.Ldobj : OpCodes.Ldind_Ref
};
}

Expand Down

0 comments on commit 247c75c

Please sign in to comment.