diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
index a90ab5c00..8a59d640d 100644
--- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
+++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
@@ -597,6 +597,101 @@ namespace ICSharpCode.Decompiler.CSharp
return result;
}
+ protected internal override TranslatedExpression VisitCompoundAssignmentInstruction(CompoundAssignmentInstruction inst)
+ {
+ switch (inst.Operator) {
+ case BinaryNumericOperator.Add:
+ return HandleCompoundAssigment(inst, AssignmentOperatorType.Add);
+ case BinaryNumericOperator.Sub:
+ return HandleCompoundAssigment(inst, AssignmentOperatorType.Subtract);
+ case BinaryNumericOperator.Mul:
+ return HandleCompoundAssigment(inst, AssignmentOperatorType.Multiply);
+ case BinaryNumericOperator.Div:
+ return HandleCompoundAssigment(inst, AssignmentOperatorType.Divide);
+ case BinaryNumericOperator.Rem:
+ return HandleCompoundAssigment(inst, AssignmentOperatorType.Modulus);
+ case BinaryNumericOperator.BitAnd:
+ return HandleCompoundAssigment(inst, AssignmentOperatorType.BitwiseAnd);
+ case BinaryNumericOperator.BitOr:
+ return HandleCompoundAssigment(inst, AssignmentOperatorType.BitwiseOr);
+ case BinaryNumericOperator.BitXor:
+ return HandleCompoundAssigment(inst, AssignmentOperatorType.ExclusiveOr);
+ case BinaryNumericOperator.ShiftLeft:
+ return HandleCompoundShift(inst, AssignmentOperatorType.ShiftLeft);
+ case BinaryNumericOperator.ShiftRight:
+ return HandleCompoundShift(inst, AssignmentOperatorType.ShiftRight);
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+
+ TranslatedExpression HandleCompoundAssigment(CompoundAssignmentInstruction inst, AssignmentOperatorType op)
+ {
+ var resolverWithOverflowCheck = resolver.WithCheckForOverflow(inst.CheckForOverflow);
+ var target = Translate(inst.Target);
+ var value = Translate(inst.Value);
+ value = PrepareArithmeticArgument(value, inst.Value.ResultType, inst.Sign);
+
+ var rr = resolverWithOverflowCheck.ResolveAssignment(op, target.ResolveResult, value.ResolveResult);
+ if (rr.IsError || rr.Type.GetStackType() != inst.ResultType
+ || !IsCompatibleWithSign(target.Type, inst.Sign) || !IsCompatibleWithSign(value.Type, inst.Sign))
+ {
+ // Target and value are incompatible, so convert value to the target type
+ // inst.ResultType should match inst.Target.ResultType
+ Debug.Assert(inst.ResultType == inst.Target.ResultType);
+ StackType targetStackType = inst.ResultType == StackType.I ? StackType.I8 : inst.ResultType;
+ IType targetType = compilation.FindType(targetStackType.ToKnownTypeCode(inst.Sign));
+ value = value.ConvertTo(targetType, this);
+ rr = resolverWithOverflowCheck.ResolveAssignment(op, target.ResolveResult, value.ResolveResult);
+ }
+ var resultExpr = new AssignmentExpression(target.Expression, op, value.Expression)
+ .WithILInstruction(inst)
+ .WithRR(rr);
+ if (AssignmentOperatorMightCheckForOverflow(op))
+ resultExpr.Expression.AddAnnotation(inst.CheckForOverflow ? AddCheckedBlocks.CheckedAnnotation : AddCheckedBlocks.UncheckedAnnotation);
+ return resultExpr;
+ }
+
+ TranslatedExpression HandleCompoundShift(CompoundAssignmentInstruction inst, AssignmentOperatorType op)
+ {
+ var target = Translate(inst.Target);
+ var value = Translate(inst.Value);
+
+ IType targetType;
+ if (inst.ResultType == StackType.I4)
+ targetType = compilation.FindType(inst.Sign == Sign.Unsigned ? KnownTypeCode.UInt32 : KnownTypeCode.Int32);
+ else
+ targetType = compilation.FindType(inst.Sign == Sign.Unsigned ? KnownTypeCode.UInt64 : KnownTypeCode.Int64);
+ target = target.ConvertTo(targetType, this);
+
+ // Shift operators in C# always expect type 'int' on the right-hand-side
+ value = value.ConvertTo(compilation.FindType(KnownTypeCode.Int32), this);
+
+ TranslatedExpression result = new AssignmentExpression(target.Expression, op, value.Expression)
+ .WithILInstruction(inst)
+ .WithRR(resolver.ResolveAssignment(op, target.ResolveResult, value.ResolveResult));
+ if (inst.ResultType == StackType.I) {
+ // C# doesn't have shift operators for IntPtr, so we first shifted a long/ulong,
+ // and now have to case back down to IntPtr/UIntPtr:
+ result = result.ConvertTo(compilation.FindType(inst.Sign == Sign.Unsigned ? KnownTypeCode.UIntPtr : KnownTypeCode.IntPtr), this);
+ }
+ return result;
+ }
+
+ static bool AssignmentOperatorMightCheckForOverflow(AssignmentOperatorType op)
+ {
+ switch (op) {
+ case AssignmentOperatorType.BitwiseAnd:
+ case AssignmentOperatorType.BitwiseOr:
+ case AssignmentOperatorType.ExclusiveOr:
+ case AssignmentOperatorType.ShiftLeft:
+ case AssignmentOperatorType.ShiftRight:
+ return false;
+ default:
+ return true;
+ }
+ }
+
protected internal override TranslatedExpression VisitConv(Conv inst)
{
var arg = Translate(inst.Argument);
@@ -1050,12 +1145,12 @@ namespace ICSharpCode.Decompiler.CSharp
// {
// return Assignment(ConvertField(inst.Field, inst.Target).WithoutILInstruction(), Translate(inst.Value)).WithILInstruction(inst);
// }
-//
+//
// protected internal override TranslatedExpression VisitLdsFld(LdsFld inst)
// {
// return ConvertField(inst.Field).WithILInstruction(inst);
// }
-//
+//
// protected internal override TranslatedExpression VisitStsFld(StsFld inst)
// {
// return Assignment(ConvertField(inst.Field).WithoutILInstruction(), Translate(inst.Value)).WithILInstruction(inst);
diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
index c6f077acb..4db9ec8e7 100644
--- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
+++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
@@ -106,6 +106,7 @@
+
diff --git a/ICSharpCode.Decompiler/IL/Instructions.cs b/ICSharpCode.Decompiler/IL/Instructions.cs
index 099991e4f..e9d3c71e3 100644
--- a/ICSharpCode.Decompiler/IL/Instructions.cs
+++ b/ICSharpCode.Decompiler/IL/Instructions.cs
@@ -45,6 +45,8 @@ namespace ICSharpCode.Decompiler.IL
LogicNot,
/// Common instruction for add, sub, mul, div, rem, bit.and, bit.or, bit.xor, shl and shr.
BinaryNumericInstruction,
+ /// Common instruction for compound assignments.
+ CompoundAssignmentInstruction,
/// Bitwise NOT
BitNot,
/// Retrieves the RuntimeArgumentHandle.
@@ -718,6 +720,84 @@ namespace ICSharpCode.Decompiler.IL
}
}
+ /// Common instruction for compound assignments.
+ public sealed partial class CompoundAssignmentInstruction : ILInstruction
+ {
+ public static readonly SlotInfo TargetSlot = new SlotInfo("Target", canInlineInto: true);
+ ILInstruction target;
+ public ILInstruction Target {
+ get { return this.target; }
+ set {
+ ValidateChild(value);
+ SetChildInstruction(ref this.target, value, 0);
+ }
+ }
+ public static readonly SlotInfo ValueSlot = new SlotInfo("Value", canInlineInto: true);
+ ILInstruction value;
+ public ILInstruction Value {
+ get { return this.value; }
+ set {
+ ValidateChild(value);
+ SetChildInstruction(ref this.value, value, 1);
+ }
+ }
+ protected sealed override int GetChildCount()
+ {
+ return 2;
+ }
+ protected sealed override ILInstruction GetChild(int index)
+ {
+ switch (index) {
+ case 0:
+ return this.target;
+ case 1:
+ return this.value;
+ default:
+ throw new IndexOutOfRangeException();
+ }
+ }
+ protected sealed override void SetChild(int index, ILInstruction value)
+ {
+ switch (index) {
+ case 0:
+ this.Target = value;
+ break;
+ case 1:
+ this.Value = value;
+ break;
+ default:
+ throw new IndexOutOfRangeException();
+ }
+ }
+ protected sealed override SlotInfo GetChildSlot(int index)
+ {
+ switch (index) {
+ case 0:
+ return TargetSlot;
+ case 1:
+ return ValueSlot;
+ default:
+ throw new IndexOutOfRangeException();
+ }
+ }
+ public sealed override ILInstruction Clone()
+ {
+ var clone = (CompoundAssignmentInstruction)ShallowClone();
+ clone.Target = this.target.Clone();
+ clone.Value = this.value.Clone();
+ return clone;
+ }
+ public override StackType ResultType { get { return target.ResultType; } }
+ public override void AcceptVisitor(ILVisitor visitor)
+ {
+ visitor.VisitCompoundAssignmentInstruction(this);
+ }
+ public override T AcceptVisitor(ILVisitor visitor)
+ {
+ return visitor.VisitCompoundAssignmentInstruction(this);
+ }
+ }
+
/// Bitwise NOT
public sealed partial class BitNot : UnaryInstruction
{
@@ -2922,6 +3002,10 @@ namespace ICSharpCode.Decompiler.IL
{
Default(inst);
}
+ protected internal virtual void VisitCompoundAssignmentInstruction(CompoundAssignmentInstruction inst)
+ {
+ Default(inst);
+ }
protected internal virtual void VisitBitNot(BitNot inst)
{
Default(inst);
@@ -3180,6 +3264,10 @@ namespace ICSharpCode.Decompiler.IL
{
return Default(inst);
}
+ protected internal virtual T VisitCompoundAssignmentInstruction(CompoundAssignmentInstruction inst)
+ {
+ return Default(inst);
+ }
protected internal virtual T VisitBitNot(BitNot inst)
{
return Default(inst);
@@ -3420,6 +3508,7 @@ namespace ICSharpCode.Decompiler.IL
"PinnedRegion",
"logic.not",
"binary",
+ "compound",
"bit.not",
"arglist",
"br",
diff --git a/ICSharpCode.Decompiler/IL/Instructions.tt b/ICSharpCode.Decompiler/IL/Instructions.tt
index 96ed0bc88..29f327df7 100644
--- a/ICSharpCode.Decompiler/IL/Instructions.tt
+++ b/ICSharpCode.Decompiler/IL/Instructions.tt
@@ -60,6 +60,9 @@
ResultType("I4"), Unary),
new OpCode("binary", "Common instruction for add, sub, mul, div, rem, bit.and, bit.or, bit.xor, shl and shr.",
CustomClassName("BinaryNumericInstruction"), Binary, CustomWriteTo, CustomConstructor, CustomComputeFlags),
+ new OpCode("compound", "Common instruction for compound assignments.",
+ CustomClassName("CompoundAssignmentInstruction"), CustomConstructor, CustomComputeFlags,
+ MayThrow, CustomArguments("target", "value"), ResultType("target.ResultType"), CustomWriteTo),
new OpCode("bit.not", "Bitwise NOT", Unary),
new OpCode("arglist", "Retrieves the RuntimeArgumentHandle.", NoArguments, ResultType("O")),
new OpCode("br", "Unconditional branch. goto target;",
diff --git a/ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs
index 74c63f283..02dc4d478 100644
--- a/ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs
+++ b/ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs
@@ -17,22 +17,16 @@
// DEALINGS IN THE SOFTWARE.
using System;
-using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+
+using ICSharpCode.NRefactory.TypeSystem;
+
namespace ICSharpCode.Decompiler.IL
-{
- public enum CompoundAssignmentType : byte
- {
- None,
- EvaluatesToOldValue,
- EvaluatesToNewValue
- }
-
+{
public enum BinaryNumericOperator : byte
{
+ None,
Add,
Sub,
Mul,
@@ -74,21 +68,6 @@ namespace ICSharpCode.Decompiler.IL
this.Operator = op;
this.resultType = ComputeResultType(op, left.ResultType, right.ResultType);
Debug.Assert(resultType != StackType.Unknown);
- //Debug.Assert(CompoundAssignmentType == CompoundAssignmentType.None || IsValidCompoundAssignmentTarget(Left));
- }
-
- internal static bool IsValidCompoundAssignmentTarget(ILInstruction inst)
- {
- switch (inst.OpCode) {
- case OpCode.LdLoc:
- case OpCode.LdObj:
- return true;
- case OpCode.Call:
- case OpCode.CallVirt:
- return true; // TODO: check if corresponding setter exists
- default:
- return false;
- }
}
internal static StackType ComputeResultType(BinaryNumericOperator op, StackType left, StackType right)
diff --git a/ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs
new file mode 100644
index 000000000..b78fa11b1
--- /dev/null
+++ b/ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs
@@ -0,0 +1,150 @@
+// Copyright (c) 2016 Siegfried Pammer
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this
+// software and associated documentation files (the "Software"), to deal in the Software
+// without restriction, including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
+// to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or
+// substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+using System;
+using System.Diagnostics;
+using System.Linq;
+
+using ICSharpCode.NRefactory.TypeSystem;
+
+namespace ICSharpCode.Decompiler.IL
+{
+ public enum CompoundAssignmentType : byte
+ {
+ EvaluatesToOldValue,
+ EvaluatesToNewValue
+ }
+
+ public partial class CompoundAssignmentInstruction : ILInstruction
+ {
+ ///
+ /// Gets whether the instruction checks for overflow.
+ ///
+ public readonly bool CheckForOverflow;
+
+ ///
+ /// For integer operations that depend on the sign, specifies whether the operation
+ /// is signed or unsigned.
+ /// For instructions that produce the same result for either sign, returns Sign.None.
+ ///
+ public readonly Sign Sign;
+
+ ///
+ /// The operator used by this assignment operator instruction.
+ ///
+ public readonly BinaryNumericOperator Operator;
+
+ public readonly CompoundAssignmentType CompoundAssignmentType;
+
+ public CompoundAssignmentInstruction(BinaryNumericOperator op, ILInstruction target, ILInstruction value, bool checkForOverflow, Sign sign, CompoundAssignmentType compoundAssigmentType)
+ : base(OpCode.CompoundAssignmentInstruction)
+ {
+ this.CheckForOverflow = checkForOverflow;
+ this.Sign = sign;
+ this.Operator = op;
+ this.Target = target;
+ this.Value = value;
+ this.CompoundAssignmentType = compoundAssigmentType;
+ Debug.Assert(compoundAssigmentType == CompoundAssignmentType.EvaluatesToNewValue || (op == BinaryNumericOperator.Add || op == BinaryNumericOperator.Sub));
+ Debug.Assert(IsValidCompoundAssignmentTarget(Target));
+ }
+
+ internal static bool IsValidCompoundAssignmentTarget(ILInstruction inst)
+ {
+ switch (inst.OpCode) {
+ case OpCode.LdLoc:
+ case OpCode.LdObj:
+ return true;
+ case OpCode.Call:
+ case OpCode.CallVirt:
+ var owner = ((CallInstruction)inst).Method.AccessorOwner as IProperty;
+ return owner != null && owner.CanSet;
+ default:
+ return false;
+ }
+ }
+
+ protected override InstructionFlags ComputeFlags()
+ {
+ var flags = target.Flags | value.Flags | InstructionFlags.SideEffect;
+ if (CheckForOverflow || (Operator == BinaryNumericOperator.Div || Operator == BinaryNumericOperator.Rem))
+ flags |= InstructionFlags.MayThrow;
+ return flags;
+ }
+
+ public override InstructionFlags DirectFlags {
+ get {
+ var flags = InstructionFlags.SideEffect;
+ if (Operator == BinaryNumericOperator.Div || Operator == BinaryNumericOperator.Rem)
+ flags |= InstructionFlags.MayThrow;
+ return flags;
+ }
+ }
+
+ string GetOperatorName(BinaryNumericOperator @operator)
+ {
+ switch (@operator) {
+ case BinaryNumericOperator.Add:
+ return "add";
+ case BinaryNumericOperator.Sub:
+ return "sub";
+ case BinaryNumericOperator.Mul:
+ return "mul";
+ case BinaryNumericOperator.Div:
+ return "div";
+ case BinaryNumericOperator.Rem:
+ return "rem";
+ case BinaryNumericOperator.BitAnd:
+ return "bit.and";
+ case BinaryNumericOperator.BitOr:
+ return "bit.or";
+ case BinaryNumericOperator.BitXor:
+ return "bit.xor";
+ case BinaryNumericOperator.ShiftLeft:
+ return "bit.shl";
+ case BinaryNumericOperator.ShiftRight:
+ return "bit.shr";
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+
+ public override void WriteTo(ITextOutput output)
+ {
+ output.Write(OpCode);
+ output.Write("." + GetOperatorName(Operator));
+ if (CompoundAssignmentType == CompoundAssignmentType.EvaluatesToNewValue)
+ output.Write(".new");
+ else
+ output.Write(".old");
+ if (CheckForOverflow)
+ output.Write(".ovf");
+ if (Sign == Sign.Unsigned)
+ output.Write(".unsigned");
+ else if (Sign == Sign.Signed)
+ output.Write(".signed");
+ output.Write('(');
+ Target.WriteTo(output);
+ output.Write(", ");
+ Value.WriteTo(output);
+ output.Write(')');
+ }
+ }
+}
+
+
diff --git a/ICSharpCode.Decompiler/IL/Instructions/PatternMatching.cs b/ICSharpCode.Decompiler/IL/Instructions/PatternMatching.cs
index c728c5650..77c219bb8 100644
--- a/ICSharpCode.Decompiler/IL/Instructions/PatternMatching.cs
+++ b/ICSharpCode.Decompiler/IL/Instructions/PatternMatching.cs
@@ -221,6 +221,21 @@ namespace ICSharpCode.Decompiler.IL
return false;
}
+ public bool MatchBinaryNumericInstruction(out BinaryNumericOperator @operator, out ILInstruction left, out ILInstruction right)
+ {
+ var op = this as BinaryNumericInstruction;
+ if (op != null) {
+ @operator = op.Operator;
+ left = op.Left;
+ right = op.Right;
+ return true;
+ }
+ @operator = BinaryNumericOperator.None;
+ left = null;
+ right = null;
+ return false;
+ }
+
///
/// If this instruction is a conversion of the specified kind, return its argument.
/// Otherwise, return the instruction itself.
diff --git a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs
index 609aedf7d..357d611e2 100644
--- a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs
+++ b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs
@@ -188,6 +188,24 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// => stloc(v, ...)
inst.ReplaceWith(new StLoc(v, inst.Value));
}
+
+ ILInstruction target;
+ IType t;
+ BinaryNumericInstruction binary = inst.Value as BinaryNumericInstruction;
+ if (binary != null && binary.Left.MatchLdObj(out target, out t) && IsSameTarget(inst.Target, target)) {
+ // stobj(target, binary.op(ldobj(target), ...))
+ // => compound.op(target, ...)
+ inst.ReplaceWith(new CompoundAssignmentInstruction(binary.Operator, binary.Left, binary.Right, binary.CheckForOverflow, binary.Sign, CompoundAssignmentType.EvaluatesToNewValue));
+ }
+ }
+
+ bool IsSameTarget(ILInstruction target, ILInstruction left)
+ {
+ IField f, f2;
+ ILInstruction t, t2;
+ if (target.MatchLdFlda(out t, out f) && left.MatchLdFlda(out t2, out f2) && f.Equals(f2))
+ return true;
+ return false;
}
protected internal override void VisitIfInstruction(IfInstruction inst)
diff --git a/ICSharpCode.Decompiler/Tests/TestCases/Pretty/CompoundAssignmentTest.cs b/ICSharpCode.Decompiler/Tests/TestCases/Pretty/CompoundAssignmentTest.cs
index 8a05baba6..07e18ec31 100644
--- a/ICSharpCode.Decompiler/Tests/TestCases/Pretty/CompoundAssignmentTest.cs
+++ b/ICSharpCode.Decompiler/Tests/TestCases/Pretty/CompoundAssignmentTest.cs
@@ -22,6 +22,8 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
public class CompoundAssignmentTest
{
+ private int test1;
+
public static void Main()
{
@@ -37,5 +39,19 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
V_0 -= i;
}
}
+
+ public void IntegerWithInline(int i)
+ {
+ Console.WriteLine(i += 5);
+ Console.WriteLine(i);
+ }
+
+ public void IntegerField(int i)
+ {
+ Console.WriteLine(this.test1 += i);
+ Console.WriteLine(this.test1);
+ Console.WriteLine(this.test1 -= i);
+ Console.WriteLine(this.test1);
+ }
}
}
diff --git a/ICSharpCode.Decompiler/Tests/TestCases/Pretty/CompoundAssignmentTest.il b/ICSharpCode.Decompiler/Tests/TestCases/Pretty/CompoundAssignmentTest.il
index e34b0bf24..2135537a1 100644
--- a/ICSharpCode.Decompiler/Tests/TestCases/Pretty/CompoundAssignmentTest.il
+++ b/ICSharpCode.Decompiler/Tests/TestCases/Pretty/CompoundAssignmentTest.il
@@ -10,7 +10,7 @@
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
-.assembly '2lky0ish'
+.assembly baqif21x
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
@@ -20,15 +20,15 @@
.hash algorithm 0x00008004
.ver 0:0:0:0
}
-.module '2lky0ish.exe'
-// MVID: {EF50960E-81BF-4C58-B168-629EA572CC14}
+.module baqif21x.exe
+// MVID: {1149F1EE-8A3E-4309-9B0E-D81380AC971E}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
-// Image base: 0x00D20000
+// Image base: 0x011D0000
// =============== CLASS MEMBERS DECLARATION ===================
@@ -36,6 +36,7 @@
.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest
extends [mscorlib]System.Object
{
+ .field private int32 test1
.method public hidebysig static void Main() cil managed
{
.entrypoint
@@ -48,7 +49,7 @@
.method public hidebysig instance void
Integer(int32 i) cil managed
{
- // Code size 25 (0x19)
+ // Code size 29 (0x1d)
.maxstack 2
.locals init (int32 V_0,
bool V_1)
@@ -62,21 +63,84 @@
IL_0008: ceq
IL_000a: stloc.1
IL_000b: ldloc.1
- IL_000c: brtrue.s IL_0014
-
- IL_000e: ldloc.0
- IL_000f: ldarg.1
- IL_0010: add
- IL_0011: stloc.0
- IL_0012: br.s IL_0018
-
- IL_0014: ldloc.0
- IL_0015: ldarg.1
- IL_0016: sub
- IL_0017: stloc.0
- IL_0018: ret
+ IL_000c: brtrue.s IL_0016
+
+ IL_000e: nop
+ IL_000f: ldloc.0
+ IL_0010: ldarg.1
+ IL_0011: add
+ IL_0012: stloc.0
+ IL_0013: nop
+ IL_0014: br.s IL_001c
+
+ IL_0016: nop
+ IL_0017: ldloc.0
+ IL_0018: ldarg.1
+ IL_0019: sub
+ IL_001a: stloc.0
+ IL_001b: nop
+ IL_001c: ret
} // end of method CompoundAssignmentTest::Integer
+ .method public hidebysig instance void
+ IntegerWithInline(int32 i) cil managed
+ {
+ // Code size 21 (0x15)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldarg.1
+ IL_0002: ldc.i4.5
+ IL_0003: add
+ IL_0004: dup
+ IL_0005: starg.s i
+ IL_0007: call void [mscorlib]System.Console::WriteLine(int32)
+ IL_000c: nop
+ IL_000d: ldarg.1
+ IL_000e: call void [mscorlib]System.Console::WriteLine(int32)
+ IL_0013: nop
+ IL_0014: ret
+ } // end of method CompoundAssignmentTest::IntegerWithInline
+
+ .method public hidebysig instance void
+ IntegerField(int32 i) cil managed
+ {
+ // Code size 72 (0x48)
+ .maxstack 3
+ .locals init (int32 V_0)
+ IL_0000: nop
+ IL_0001: ldarg.0
+ IL_0002: dup
+ IL_0003: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::test1
+ IL_0008: ldarg.1
+ IL_0009: add
+ IL_000a: dup
+ IL_000b: stloc.0
+ IL_000c: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::test1
+ IL_0011: ldloc.0
+ IL_0012: call void [mscorlib]System.Console::WriteLine(int32)
+ IL_0017: nop
+ IL_0018: ldarg.0
+ IL_0019: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::test1
+ IL_001e: call void [mscorlib]System.Console::WriteLine(int32)
+ IL_0023: nop
+ IL_0024: ldarg.0
+ IL_0025: dup
+ IL_0026: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::test1
+ IL_002b: ldarg.1
+ IL_002c: sub
+ IL_002d: dup
+ IL_002e: stloc.0
+ IL_002f: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::test1
+ IL_0034: ldloc.0
+ IL_0035: call void [mscorlib]System.Console::WriteLine(int32)
+ IL_003a: nop
+ IL_003b: ldarg.0
+ IL_003c: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.CompoundAssignmentTest::test1
+ IL_0041: call void [mscorlib]System.Console::WriteLine(int32)
+ IL_0046: nop
+ IL_0047: ret
+ } // end of method CompoundAssignmentTest::IntegerField
+
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{