As per IRC discussion, here is combined patch for add, dup, and stfld
instructions, complete with testcases.
As a result, following source code can be decompiled.
public class TestCase {
int v;
public void InPlaceAdd(int n) {
v += n;
}
}
--
Seo Sanghyeon
--~--~---------~--~----~------------~-------~--~----~
--
mono-cecil
-~----------~----~----~----~------~----~------~--~---
Index: Cecil.FlowAnalysis/ActionFlow/ActionFlowGraphBuilder.cs
===================================================================
--- Cecil.FlowAnalysis/ActionFlow/ActionFlowGraphBuilder.cs (revision 91032)
+++ Cecil.FlowAnalysis/ActionFlow/ActionFlowGraphBuilder.cs (working copy)
@@ -447,6 +447,11 @@
Add (new AssignActionBlock (instruction,
(AssignExpression) Pop ()));
}
+ public override void OnStfld (Instruction instruction)
+ {
+ Add (new AssignActionBlock (instruction,
(AssignExpression) Pop ()));
+ }
+
int GetStackBefore (Instruction instruction)
{
return GetInstructionData (instruction).StackBefore;
Index: Cecil.FlowAnalysis/ActionFlow/ExpressionDecompiler.cs
===================================================================
--- Cecil.FlowAnalysis/ActionFlow/ExpressionDecompiler.cs (revision 91032)
+++ Cecil.FlowAnalysis/ActionFlow/ExpressionDecompiler.cs (working copy)
@@ -67,6 +67,17 @@
Push (new AssignExpression (Pop (), Pop ()));
}
+ public override void OnStfld (Instruction instruction)
+ {
+ FieldReference field =
(FieldReference)instruction.Operand;
+ Expression expression = Pop ();
+ Expression target = Pop ();
+ Push (
+ new AssignExpression (
+ new FieldReferenceExpression (target,
field),
+ expression));
+ }
+
public override void OnCallvirt (Instruction instruction)
{
OnCall (instruction);
@@ -100,12 +111,25 @@
new MethodReferenceExpression (target,
method), args));
}
+ public override void OnDup (Instruction instruction)
+ {
+ Expression expression = Pop ();
+ Push (expression);
+ Push (expression);
+ }
+
public override void OnPop (Instruction instruction)
{
}
- public override void OnMul (Mono.Cecil.Cil.Instruction
instruction)
+ public override void OnAdd (Instruction instruction)
{
+ BinaryOperator op = BinaryOperator.Add;
+ PushBinaryExpression (op);
+ }
+
+ public override void OnMul (Instruction instruction)
+ {
BinaryOperator op = BinaryOperator.Multiply;
PushBinaryExpression (op);
}
Index: Cecil.FlowAnalysis/CodeStructure/BinaryOperator.cs
===================================================================
--- Cecil.FlowAnalysis/CodeStructure/BinaryOperator.cs (revision 91032)
+++ Cecil.FlowAnalysis/CodeStructure/BinaryOperator.cs (working copy)
@@ -26,6 +26,7 @@
namespace Cecil.FlowAnalysis.CodeStructure {
public enum BinaryOperator {
None,
+ Add,
Multiply,
ValueEquality,
ValueInequality,
Index: Cecil.FlowAnalysis/CodeStructure/ExpressionPrinter.cs
===================================================================
--- Cecil.FlowAnalysis/CodeStructure/ExpressionPrinter.cs (revision 91032)
+++ Cecil.FlowAnalysis/CodeStructure/ExpressionPrinter.cs (working copy)
@@ -168,6 +168,7 @@
switch (op) {
case BinaryOperator.LogicalAnd: return "&&";
case BinaryOperator.LogicalOr: return "||";
+ case BinaryOperator.Add: return "+";
case BinaryOperator.Multiply: return "*";
case BinaryOperator.ValueEquality: return "==";
case BinaryOperator.ValueInequality: return "!=";
Index: testcases/FlowAnalysis/InPlaceAdd.il
===================================================================
--- testcases/FlowAnalysis/InPlaceAdd.il (revision 0)
+++ testcases/FlowAnalysis/InPlaceAdd.il (revision 0)
@@ -0,0 +1,18 @@
+.assembly TestCase {}
+
+.class public auto ansi beforefieldinit TestCase
+ extends [mscorlib]System.Object
+{
+ .field int32 v
+
+ .method public hidebysig void Main(int32 n) cil managed
+ {
+ IL_0000: ldarg.0
+ IL_0001: dup
+ IL_0002: ldfld int32 TestCase::v
+ IL_0007: ldarg.1
+ IL_0008: add
+ IL_0009: stfld int32 TestCase::v
+ IL_000e: ret
+ }
+}
Index: testcases/FlowAnalysis/InPlaceAdd-afg.txt
===================================================================
--- testcases/FlowAnalysis/InPlaceAdd-afg.txt (revision 0)
+++ testcases/FlowAnalysis/InPlaceAdd-afg.txt (revision 0)
@@ -0,0 +1,2 @@
+this.v = (this.v + n)
+return