Browse Source

Add missing members to IL pattern matching.

pull/728/merge
Siegfried Pammer 9 years ago
parent
commit
7689e99e1c
  1. 20
      ICSharpCode.Decompiler/IL/Instructions.cs
  2. 31
      ICSharpCode.Decompiler/IL/Instructions.tt

20
ICSharpCode.Decompiler/IL/Instructions.cs

@ -879,7 +879,7 @@ namespace ICSharpCode.Decompiler.IL @@ -879,7 +879,7 @@ namespace ICSharpCode.Decompiler.IL
protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match)
{
var o = other as CompoundAssignmentInstruction;
return o != null && this.target.PerformMatch(o.target, ref match) && this.value.PerformMatch(o.value, ref match) && type.Equals(o.type);
return o != null && this.target.PerformMatch(o.target, ref match) && this.value.PerformMatch(o.value, ref match) && type.Equals(o.type) && CheckForOverflow == o.CheckForOverflow && Sign == o.Sign && Operator == o.Operator;
}
}
@ -977,7 +977,7 @@ namespace ICSharpCode.Decompiler.IL @@ -977,7 +977,7 @@ namespace ICSharpCode.Decompiler.IL
protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match)
{
var o = other as Leave;
return o != null;
return o != null && this.TargetContainer == o.TargetContainer;
}
}
@ -1103,7 +1103,7 @@ namespace ICSharpCode.Decompiler.IL @@ -1103,7 +1103,7 @@ namespace ICSharpCode.Decompiler.IL
protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match)
{
var o = other as SwitchInstruction;
return o != null;
return o != null && Value.PerformMatch(o.Value, ref match) && Patterns.ListMatch.DoMatch(this.Sections, o.Sections, ref match);
}
}
@ -1173,7 +1173,7 @@ namespace ICSharpCode.Decompiler.IL @@ -1173,7 +1173,7 @@ namespace ICSharpCode.Decompiler.IL
protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match)
{
var o = other as SwitchSection;
return o != null && this.body.PerformMatch(o.body, ref match);
return o != null && this.body.PerformMatch(o.body, ref match) && this.Labels.Intervals.SequenceEqual(o.Labels.Intervals);
}
}
@ -1196,7 +1196,7 @@ namespace ICSharpCode.Decompiler.IL @@ -1196,7 +1196,7 @@ namespace ICSharpCode.Decompiler.IL
protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match)
{
var o = other as TryCatch;
return o != null;
return o != null && TryBlock.PerformMatch(o.TryBlock, ref match) && Patterns.ListMatch.DoMatch(Handlers, o.Handlers, ref match);
}
}
@ -1336,7 +1336,7 @@ namespace ICSharpCode.Decompiler.IL @@ -1336,7 +1336,7 @@ namespace ICSharpCode.Decompiler.IL
protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match)
{
var o = other as TryFinally;
return o != null;
return o != null && TryBlock.PerformMatch(o.TryBlock, ref match) && finallyBlock.PerformMatch(o.finallyBlock, ref match);
}
}
@ -1359,7 +1359,7 @@ namespace ICSharpCode.Decompiler.IL @@ -1359,7 +1359,7 @@ namespace ICSharpCode.Decompiler.IL
protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match)
{
var o = other as TryFault;
return o != null;
return o != null && TryBlock.PerformMatch(o.TryBlock, ref match) && faultBlock.PerformMatch(o.faultBlock, ref match);
}
}
@ -1417,7 +1417,7 @@ namespace ICSharpCode.Decompiler.IL @@ -1417,7 +1417,7 @@ namespace ICSharpCode.Decompiler.IL
protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match)
{
var o = other as Comp;
return o != null && this.Left.PerformMatch(o.Left, ref match) && this.Right.PerformMatch(o.Right, ref match) && this.Kind == o.Kind;
return o != null && this.Left.PerformMatch(o.Left, ref match) && this.Right.PerformMatch(o.Right, ref match) && this.Kind == o.Kind && this.Sign == o.Sign;
}
}
@ -1517,7 +1517,7 @@ namespace ICSharpCode.Decompiler.IL @@ -1517,7 +1517,7 @@ namespace ICSharpCode.Decompiler.IL
protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match)
{
var o = other as Conv;
return o != null && this.Argument.PerformMatch(o.Argument, ref match);
return o != null && this.Argument.PerformMatch(o.Argument, ref match) && CheckForOverflow == o.CheckForOverflow && Kind == o.Kind && InputSign == o.InputSign && TargetType == o.TargetType;
}
}
@ -2275,7 +2275,7 @@ namespace ICSharpCode.Decompiler.IL @@ -2275,7 +2275,7 @@ namespace ICSharpCode.Decompiler.IL
protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match)
{
var o = other as Return;
return o != null;
return o != null && this.hasArgument == o.hasArgument && (!hasArgument || this.ReturnValue.PerformMatch(o.ReturnValue, ref match));
}
}

31
ICSharpCode.Decompiler/IL/Instructions.tt

@ -67,14 +67,16 @@ @@ -67,14 +67,16 @@
MatchCondition("CheckForOverflow == o.CheckForOverflow && Sign == o.Sign && Operator == o.Operator")),
new OpCode("compound", "Common instruction for compound assignments.",
CustomClassName("CompoundAssignmentInstruction"), CustomConstructor, CustomComputeFlags,
MayThrow, CustomArguments("target", "value"), HasTypeOperand, ResultType("type.GetStackType()"), CustomWriteTo),
MayThrow, CustomArguments("target", "value"), HasTypeOperand, ResultType("type.GetStackType()"), CustomWriteTo,
MatchCondition("CheckForOverflow == o.CheckForOverflow && Sign == o.Sign && Operator == o.Operator")),
new OpCode("bit.not", "Bitwise NOT", Unary),
new OpCode("arglist", "Retrieves the RuntimeArgumentHandle.", NoArguments, ResultType("O")),
new OpCode("br", "Unconditional branch. <c>goto target;</c>",
CustomClassName("Branch"), NoArguments, CustomConstructor, UnconditionalBranch, MayBranch, CustomComputeFlags,
MatchCondition("this.TargetBlock == o.TargetBlock")),
new OpCode("leave", "Unconditional branch to end of block container. <c>goto container_end;</c>, often <c>break;</c>",
NoArguments, CustomConstructor, UnconditionalBranch, MayBranch, CustomComputeFlags),
NoArguments, CustomConstructor, UnconditionalBranch, MayBranch, CustomComputeFlags,
MatchCondition("this.TargetContainer == o.TargetContainer")),
new OpCode("if", "If statement / conditional expression. <c>if (condition) trueExpr else falseExpr</c>",
CustomClassName("IfInstruction"),
CustomChildren(new []{
@ -83,21 +85,28 @@ @@ -83,21 +85,28 @@
new ChildInfo("falseInst"),
}), CustomConstructor, CustomComputeFlags, CustomWriteTo),
new OpCode("switch", "Switch statement",
CustomClassName("SwitchInstruction"), CustomConstructor, CustomComputeFlags, CustomWriteTo, ResultType("Void")),
CustomClassName("SwitchInstruction"), CustomConstructor, CustomComputeFlags, CustomWriteTo, ResultType("Void"),
MatchCondition("Value.PerformMatch(o.Value, ref match) && Patterns.ListMatch.DoMatch(this.Sections, o.Sections, ref match)")),
new OpCode("switch.section", "Switch section within a switch statement",
CustomClassName("SwitchSection"), CustomChildren(new [] { new ChildInfo("body") }),
CustomConstructor, CustomComputeFlags, CustomWriteTo, ResultType("Void")),
CustomConstructor, CustomComputeFlags, CustomWriteTo, ResultType("Void"),
MatchCondition("this.Labels.Intervals.SequenceEqual(o.Labels.Intervals)")),
new OpCode("try.catch", "Try-catch statement.",
BaseClass("TryInstruction"), CustomConstructor, CustomComputeFlags, CustomWriteTo),
BaseClass("TryInstruction"), CustomConstructor, CustomComputeFlags, CustomWriteTo,
MatchCondition("TryBlock.PerformMatch(o.TryBlock, ref match)"),
MatchCondition("Patterns.ListMatch.DoMatch(Handlers, o.Handlers, ref match)")),
new OpCode("try.catch.handler", "Catch handler within a try-catch statement.",
CustomChildren(new [] {
new ChildInfo("filter"),
new ChildInfo("body"),
}), HasVariableOperand("Store", generateCheckInvariant: false), CustomWriteTo, CustomComputeFlags),
new OpCode("try.finally", "Try-finally statement",
BaseClass("TryInstruction"), CustomConstructor, CustomWriteTo, CustomComputeFlags),
BaseClass("TryInstruction"), CustomConstructor, CustomWriteTo, CustomComputeFlags,
MatchCondition("TryBlock.PerformMatch(o.TryBlock, ref match) && finallyBlock.PerformMatch(o.finallyBlock, ref match)")),
new OpCode("try.fault", "Try-fault statement",
BaseClass("TryInstruction"), CustomConstructor, CustomWriteTo, CustomComputeFlags),
BaseClass("TryInstruction"), CustomConstructor, CustomWriteTo, CustomComputeFlags,
MatchCondition("TryBlock.PerformMatch(o.TryBlock, ref match)"),
MatchCondition("faultBlock.PerformMatch(o.faultBlock, ref match)")),
new OpCode("debug.break", "Breakpoint instruction",
NoArguments, VoidResult, SideEffect),
new OpCode("comp", "Comparison. The inputs must be both integers; or both floats; or both object references. "
@ -105,14 +114,15 @@ @@ -105,14 +114,15 @@
+ "Floating-point comparisons evaluate to 0 (false) when an input is NaN, except for 'NaN != NaN' which "
+ "evaluates to 1 (true).",
Binary, CustomConstructor, CustomWriteTo, ResultType("I4"),
MatchCondition("this.Kind == o.Kind")),
MatchCondition("this.Kind == o.Kind && this.Sign == o.Sign")),
new OpCode("call", "Non-virtual method call.", Call),
new OpCode("callvirt", "Virtual method call.",
CustomClassName("CallVirt"), Call),
new OpCode("ckfinite", "Checks that the input float is not NaN or infinite.",
Unary, MayThrow, VoidResult),
new OpCode("conv", "Numeric cast.",
Unary, CustomConstructor),
Unary, CustomConstructor,
MatchCondition("CheckForOverflow == o.CheckForOverflow && Kind == o.Kind && InputSign == o.InputSign && TargetType == o.TargetType")),
new OpCode("ldloc", "Loads the value of a local variable. (ldarg/ldloc)",
CustomClassName("LdLoc"), NoArguments, HasVariableOperand("Load"), ResultType("variable.StackType")),
new OpCode("ldloca", "Loads the address of a local variable. (ldarga/ldloca)",
@ -146,7 +156,8 @@ @@ -146,7 +156,8 @@
new OpCode("localloc", "Allocates space in the stack frame",
CustomClassName("LocAlloc"), Unary, ResultType("I"), MayThrow),
new OpCode("ret", "Returns from the current method or lambda.",
CustomClassName("Return"), CustomConstructor, CustomComputeFlags, MayBranch, UnconditionalBranch),
CustomClassName("Return"), CustomConstructor, CustomComputeFlags, MayBranch, UnconditionalBranch,
MatchCondition("this.hasArgument == o.hasArgument && (!hasArgument || this.ReturnValue.PerformMatch(o.ReturnValue, ref match))")),
new OpCode("ldflda", "Load address of instance field",
CustomClassName("LdFlda"), CustomArguments("target"), MayThrowIfNotDelayed, HasFieldOperand, ResultType("Ref")),

Loading…
Cancel
Save