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

Reply via email to