Skip to content

Commit

Permalink
Fix incorrect IL code for methods with multiple return statements
Browse files Browse the repository at this point in the history
if, switch, etc
  • Loading branch information
vanifatovvlad committed Mar 17, 2023
1 parent 2475a51 commit 10b11e3
Showing 1 changed file with 1 addition and 39 deletions.
40 changes: 1 addition & 39 deletions CodeGen/AtomWeaverV2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,9 @@ private struct AtomGetterMethodWeaver
private PropertyDefinition _property;

private string _atomDebugName;
private VariableDefinition _resultVariable;

private Instruction _nullCheckEndInstruction;
private Instruction _directEvalEndInstruction;
private Instruction _loadResultInstruction;

private MethodReference _atomCreateMethod;
private MethodReference _atomPullCtorMethod;
Expand All @@ -207,22 +205,16 @@ public AtomGetterMethodWeaver(AtomWeaverV2 weaver, PropertyDefinition property,
_atomDebugName = weaver._generateDebugNames
? $"{property.DeclaringType.FullName}::{property.Name}"
: null;
_resultVariable = new VariableDefinition(property.PropertyType);

_nullCheckEndInstruction = Instruction.Create(OpCodes.Nop);
_directEvalEndInstruction = Instruction.Create(OpCodes.Nop);
_loadResultInstruction = Instruction.Create(OpCodes.Ldloc, _resultVariable);

var propertyType = property.PropertyType;
_atomCreateMethod = Helpers.MakeGenericMethod(weaver._atomCreateMethod, propertyType);
_atomPullCtorMethod = Helpers.MakeHostInstanceGeneric(weaver._atomPullCtorMethod, propertyType);
_tryEnterMethod = Helpers.MakeHostInstanceGeneric(weaver._atomDirectEvalMethod, propertyType);
_atomGetMethod = Helpers.MakeHostInstanceGeneric(weaver._atomGetValueMethod, propertyType);
_throwIfDisposedMethod = weaver._throwIfDisposedMethod;

var body = property.GetMethod.Body;
body.InitLocals = true;
body.Variables.Add(_resultVariable);
}

public void Weave()
Expand All @@ -233,22 +225,6 @@ public void Weave()

Prepend(ref index, instructions);

while (index < instructions.Count)
{
var current = instructions[index++];
if (current.OpCode != OpCodes.Ret)
{
continue;
}

current.OpCode = OpCodes.Nop;
current.Operand = null;

ReplaceReturn(ref index, instructions);
}

Append(ref index, instructions);

body.OptimizeMacros();
}

Expand Down Expand Up @@ -300,24 +276,10 @@ private void Prepend(ref int ind, IList<Instruction> il)
il.Insert(ind++, Instruction.Create(OpCodes.Ldarg_0));
il.Insert(ind++, Instruction.Create(OpCodes.Ldfld, _atomField));
il.Insert(ind++, Instruction.Create(OpCodes.Callvirt, _atomGetMethod));
il.Insert(ind++, Instruction.Create(OpCodes.Stloc, _resultVariable));
il.Insert(ind++, Instruction.Create(OpCodes.Br, _loadResultInstruction));
il.Insert(ind++, Instruction.Create(OpCodes.Ret));

il.Insert(ind++, _directEvalEndInstruction);
}

private void ReplaceReturn(ref int ind, IList<Instruction> il)
{
il.Insert(ind++, Instruction.Create(OpCodes.Nop));
il.Insert(ind++, Instruction.Create(OpCodes.Stloc, _resultVariable));
il.Insert(ind++, Instruction.Create(OpCodes.Br, _loadResultInstruction));
}

private void Append(ref int index, IList<Instruction> il)
{
il.Insert(index++, _loadResultInstruction);
il.Insert(index++, Instruction.Create(OpCodes.Ret));
}
}

private struct AtomSetterMethodWeaver
Expand Down

0 comments on commit 10b11e3

Please sign in to comment.