Browse Source

Add HasTypeOperand to CompoundAssignmentInstruction

pull/728/merge
Siegfried Pammer 10 years ago
parent
commit
1d92df7723
  1. 4
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  2. 5
      ICSharpCode.Decompiler/IL/Instructions.cs
  3. 2
      ICSharpCode.Decompiler/IL/Instructions.tt
  4. 3
      ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs
  5. 2
      ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs
  6. 4
      ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs

4
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -639,9 +639,7 @@ namespace ICSharpCode.Decompiler.CSharp
// Target and value are incompatible, so convert value to the target type // Target and value are incompatible, so convert value to the target type
// inst.ResultType should match inst.Target.ResultType // inst.ResultType should match inst.Target.ResultType
Debug.Assert(inst.ResultType == inst.Target.ResultType); Debug.Assert(inst.ResultType == inst.Target.ResultType);
StackType targetStackType = inst.ResultType == StackType.I ? StackType.I8 : inst.ResultType; value = value.ConvertTo(inst.Type, this);
IType targetType = compilation.FindType(targetStackType.ToKnownTypeCode(inst.Sign));
value = value.ConvertTo(targetType, this);
rr = resolverWithOverflowCheck.ResolveAssignment(op, target.ResolveResult, value.ResolveResult); rr = resolverWithOverflowCheck.ResolveAssignment(op, target.ResolveResult, value.ResolveResult);
} }
TranslatedExpression resultExpr; TranslatedExpression resultExpr;

5
ICSharpCode.Decompiler/IL/Instructions.cs

@ -788,7 +788,10 @@ namespace ICSharpCode.Decompiler.IL
clone.Value = this.value.Clone(); clone.Value = this.value.Clone();
return clone; return clone;
} }
public override StackType ResultType { get { return target.ResultType; } } readonly IType type;
/// <summary>Returns the type operand.</summary>
public IType Type { get { return type; } }
public override StackType ResultType { get { return type.GetStackType(); } }
public override void AcceptVisitor(ILVisitor visitor) public override void AcceptVisitor(ILVisitor visitor)
{ {
visitor.VisitCompoundAssignmentInstruction(this); visitor.VisitCompoundAssignmentInstruction(this);

2
ICSharpCode.Decompiler/IL/Instructions.tt

@ -62,7 +62,7 @@
CustomClassName("BinaryNumericInstruction"), Binary, CustomWriteTo, CustomConstructor, CustomComputeFlags), CustomClassName("BinaryNumericInstruction"), Binary, CustomWriteTo, CustomConstructor, CustomComputeFlags),
new OpCode("compound", "Common instruction for compound assignments.", new OpCode("compound", "Common instruction for compound assignments.",
CustomClassName("CompoundAssignmentInstruction"), CustomConstructor, CustomComputeFlags, CustomClassName("CompoundAssignmentInstruction"), CustomConstructor, CustomComputeFlags,
MayThrow, CustomArguments("target", "value"), ResultType("target.ResultType"), CustomWriteTo), MayThrow, CustomArguments("target", "value"), HasTypeOperand, ResultType("type.GetStackType()"), CustomWriteTo),
new OpCode("bit.not", "Bitwise NOT", Unary), new OpCode("bit.not", "Bitwise NOT", Unary),
new OpCode("arglist", "Retrieves the RuntimeArgumentHandle.", NoArguments, ResultType("O")), new OpCode("arglist", "Retrieves the RuntimeArgumentHandle.", NoArguments, ResultType("O")),
new OpCode("br", "Unconditional branch. <c>goto target;</c>", new OpCode("br", "Unconditional branch. <c>goto target;</c>",

3
ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs

@ -51,13 +51,14 @@ namespace ICSharpCode.Decompiler.IL
public readonly CompoundAssignmentType CompoundAssignmentType; public readonly CompoundAssignmentType CompoundAssignmentType;
public CompoundAssignmentInstruction(BinaryNumericOperator op, ILInstruction target, ILInstruction value, bool checkForOverflow, Sign sign, CompoundAssignmentType compoundAssigmentType) public CompoundAssignmentInstruction(BinaryNumericOperator op, ILInstruction target, ILInstruction value, IType type, bool checkForOverflow, Sign sign, CompoundAssignmentType compoundAssigmentType)
: base(OpCode.CompoundAssignmentInstruction) : base(OpCode.CompoundAssignmentInstruction)
{ {
this.CheckForOverflow = checkForOverflow; this.CheckForOverflow = checkForOverflow;
this.Sign = sign; this.Sign = sign;
this.Operator = op; this.Operator = op;
this.Target = target; this.Target = target;
this.type = type;
this.Value = value; this.Value = value;
this.CompoundAssignmentType = compoundAssigmentType; this.CompoundAssignmentType = compoundAssigmentType;
Debug.Assert(compoundAssigmentType == CompoundAssignmentType.EvaluatesToNewValue || (op == BinaryNumericOperator.Add || op == BinaryNumericOperator.Sub)); Debug.Assert(compoundAssigmentType == CompoundAssignmentType.EvaluatesToNewValue || (op == BinaryNumericOperator.Add || op == BinaryNumericOperator.Sub));

2
ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

@ -195,7 +195,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (binary != null && binary.Left.MatchLdObj(out target, out t) && IsSameTarget(inst.Target, target)) { if (binary != null && binary.Left.MatchLdObj(out target, out t) && IsSameTarget(inst.Target, target)) {
// stobj(target, binary.op(ldobj(target), ...)) // stobj(target, binary.op(ldobj(target), ...))
// => compound.op(target, ...) // => compound.op(target, ...)
inst.ReplaceWith(new CompoundAssignmentInstruction(binary.Operator, binary.Left, binary.Right, binary.CheckForOverflow, binary.Sign, CompoundAssignmentType.EvaluatesToNewValue)); inst.ReplaceWith(new CompoundAssignmentInstruction(binary.Operator, binary.Left, binary.Right, t, binary.CheckForOverflow, binary.Sign, CompoundAssignmentType.EvaluatesToNewValue));
} }
} }

4
ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs

@ -206,7 +206,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (binary == null || !binary.Left.MatchLdLoc(nextInst.Variable) || !binary.Right.MatchLdcI4(1) if (binary == null || !binary.Left.MatchLdLoc(nextInst.Variable) || !binary.Right.MatchLdcI4(1)
|| (binary.Operator != BinaryNumericOperator.Add && binary.Operator != BinaryNumericOperator.Sub)) || (binary.Operator != BinaryNumericOperator.Add && binary.Operator != BinaryNumericOperator.Sub))
return false; return false;
var assignment = new CompoundAssignmentInstruction(binary.Operator, new LdObj(inst.Value, targetType), binary.Right, binary.CheckForOverflow, binary.Sign, CompoundAssignmentType.EvaluatesToOldValue); var assignment = new CompoundAssignmentInstruction(binary.Operator, new LdObj(inst.Value, targetType), binary.Right, targetType, binary.CheckForOverflow, binary.Sign, CompoundAssignmentType.EvaluatesToOldValue);
stobj.ReplaceWith(new StLoc(nextInst.Variable, assignment)); stobj.ReplaceWith(new StLoc(nextInst.Variable, assignment));
block.Instructions.RemoveAt(i + 1); block.Instructions.RemoveAt(i + 1);
return true; return true;
@ -255,7 +255,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (binary == null || !binary.Left.MatchLdLoc(fieldValue.Variable) || !binary.Right.MatchLdcI4(1) if (binary == null || !binary.Left.MatchLdLoc(fieldValue.Variable) || !binary.Right.MatchLdcI4(1)
|| (binary.Operator != BinaryNumericOperator.Add && binary.Operator != BinaryNumericOperator.Sub)) || (binary.Operator != BinaryNumericOperator.Add && binary.Operator != BinaryNumericOperator.Sub))
return false; return false;
var assignment = new CompoundAssignmentInstruction(binary.Operator, new LdObj(baseAddress, t), binary.Right, binary.CheckForOverflow, binary.Sign, CompoundAssignmentType.EvaluatesToOldValue); var assignment = new CompoundAssignmentInstruction(binary.Operator, new LdObj(baseAddress, t), binary.Right, t, binary.CheckForOverflow, binary.Sign, CompoundAssignmentType.EvaluatesToOldValue);
stobj.ReplaceWith(new StLoc(fieldValueCopyToLocal.Variable, assignment)); stobj.ReplaceWith(new StLoc(fieldValueCopyToLocal.Variable, assignment));
block.Instructions.RemoveAt(i + 2); block.Instructions.RemoveAt(i + 2);
block.Instructions.RemoveAt(i + 1); block.Instructions.RemoveAt(i + 1);

Loading…
Cancel
Save