Browse Source

Change some transforms to block transforms.

pull/728/merge
Daniel Grunwald 9 years ago
parent
commit
51a9786243
  1. 26
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 2
      ICSharpCode.Decompiler/DecompilerSettings.cs
  3. 3
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  4. 81
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.ruleset
  5. 12
      ICSharpCode.Decompiler/IL/Transforms/BlockTransform.cs
  6. 58
      ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs
  7. 16
      ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs
  8. 10
      ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs
  9. 22
      ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs
  10. 44
      ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs
  11. 3
      ICSharpCode.Decompiler/Properties/AssemblyInfo.template.cs
  12. 6
      ICSharpCode.Decompiler/Tests/RoundtripAssembly.cs
  13. 1
      ILSpy/ILSpy.csproj
  14. 2
      ILSpy/Properties/AssemblyInfo.template.cs

26
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -63,21 +63,23 @@ namespace ICSharpCode.Decompiler.CSharp
new IntroduceExitPoints(), new IntroduceExitPoints(),
new BlockILTransform( // per-block transforms new BlockILTransform( // per-block transforms
new ConditionDetection(), new ConditionDetection(),
new LoopingBlockTransform( // per-block transforms that depend on each other, and thus need to loop new ILInlining(),
new TransformAssignment(),
new CopyPropagation(),
new LoopingBlockTransform(
// per-block transforms that depend on each other, and thus need to loop.
// Pretty much all transforms that open up new expression inlining
// opportunities belong in this category.
new ExpressionTransforms(),
new TransformArrayInitializers(),
new ILInlining()
) )
), ),
new ILInlining(), //new InlineCompilerGeneratedVariables(),
new TransformAssignment(), // -- isn't InlineCompilerGeneratedVariables redundant now that we have variable splitting?
new CopyPropagation(),
new InlineCompilerGeneratedVariables(),
new ExpressionTransforms(), // must run once before "the loop" to allow RemoveDeadVariablesInit
new RemoveDeadVariableInit(), // must run after ExpressionTransforms because it does not handle stobj(ldloca V, ...) new RemoveDeadVariableInit(), // must run after ExpressionTransforms because it does not handle stobj(ldloca V, ...)
new DelegateConstruction(), //new DelegateConstruction(),
new LoopingTransform( // the loop: transforms that cyclicly depend on each other // DelegateConstruction disabled because its broken since the BlockILTransform change
new ExpressionTransforms(),
new TransformArrayInitializers(),
new ILInlining()
)
}; };
} }

2
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -27,7 +27,7 @@ namespace ICSharpCode.Decompiler
/// </summary> /// </summary>
public class DecompilerSettings : INotifyPropertyChanged public class DecompilerSettings : INotifyPropertyChanged
{ {
bool anonymousMethods = true; bool anonymousMethods = false;
/// <summary> /// <summary>
/// Decompile anonymous methods/lambdas. /// Decompile anonymous methods/lambdas.

3
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -45,9 +45,11 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>false</Prefer32Bit>
<DefineConstants>TRACE;DEBUG;STEP</DefineConstants> <DefineConstants>TRACE;DEBUG;STEP</DefineConstants>
<CodeAnalysisRuleSet>ICSharpCode.Decompiler.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>false</Prefer32Bit>
<CodeAnalysisRuleSet>ICSharpCode.Decompiler.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
@ -179,6 +181,7 @@
<Compile Include="Util\Interval.cs" /> <Compile Include="Util\Interval.cs" />
<Compile Include="Util\LongSet.cs" /> <Compile Include="Util\LongSet.cs" />
<Compile Include="Util\UnionFind.cs" /> <Compile Include="Util\UnionFind.cs" />
<None Include="ICSharpCode.Decompiler.ruleset" />
<None Include="IL\ILOpCodes.tt"> <None Include="IL\ILOpCodes.tt">
<Generator>TextTemplatingFileGenerator</Generator> <Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>ILOpCodes.cs</LastGenOutput> <LastGenOutput>ILOpCodes.cs</LastGenOutput>

81
ICSharpCode.Decompiler/ICSharpCode.Decompiler.ruleset

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="Rules for ICSharpCode.Decompiler" Description="Code analysis rules for ICSharpCode.Decompiler.csproj." ToolsVersion="14.0">
<Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis" RuleNamespace="Microsoft.Rules.Managed">
<Rule Id="CA1001" Action="Warning" />
<Rule Id="CA1009" Action="Warning" />
<Rule Id="CA1016" Action="Warning" />
<Rule Id="CA1033" Action="Warning" />
<Rule Id="CA1049" Action="Warning" />
<Rule Id="CA1060" Action="Warning" />
<Rule Id="CA1061" Action="Warning" />
<Rule Id="CA1063" Action="Warning" />
<Rule Id="CA1065" Action="Warning" />
<Rule Id="CA1301" Action="Warning" />
<Rule Id="CA1400" Action="Warning" />
<Rule Id="CA1401" Action="Warning" />
<Rule Id="CA1403" Action="Warning" />
<Rule Id="CA1404" Action="Warning" />
<Rule Id="CA1405" Action="Warning" />
<Rule Id="CA1410" Action="Warning" />
<Rule Id="CA1415" Action="Warning" />
<Rule Id="CA1821" Action="Warning" />
<Rule Id="CA1900" Action="Warning" />
<Rule Id="CA1901" Action="Warning" />
<Rule Id="CA2002" Action="Warning" />
<Rule Id="CA2100" Action="Warning" />
<Rule Id="CA2101" Action="Warning" />
<Rule Id="CA2108" Action="Warning" />
<Rule Id="CA2111" Action="Warning" />
<Rule Id="CA2112" Action="Warning" />
<Rule Id="CA2114" Action="Warning" />
<Rule Id="CA2116" Action="Warning" />
<Rule Id="CA2117" Action="Warning" />
<Rule Id="CA2122" Action="Warning" />
<Rule Id="CA2123" Action="Warning" />
<Rule Id="CA2124" Action="Warning" />
<Rule Id="CA2126" Action="Warning" />
<Rule Id="CA2131" Action="Warning" />
<Rule Id="CA2132" Action="Warning" />
<Rule Id="CA2133" Action="Warning" />
<Rule Id="CA2134" Action="Warning" />
<Rule Id="CA2137" Action="Warning" />
<Rule Id="CA2138" Action="Warning" />
<Rule Id="CA2140" Action="Warning" />
<Rule Id="CA2141" Action="Warning" />
<Rule Id="CA2146" Action="Warning" />
<Rule Id="CA2147" Action="Warning" />
<Rule Id="CA2149" Action="Warning" />
<Rule Id="CA2200" Action="Warning" />
<Rule Id="CA2202" Action="Warning" />
<Rule Id="CA2207" Action="Warning" />
<Rule Id="CA2212" Action="Warning" />
<Rule Id="CA2213" Action="Warning" />
<Rule Id="CA2214" Action="Warning" />
<Rule Id="CA2216" Action="Warning" />
<Rule Id="CA2220" Action="Warning" />
<Rule Id="CA2229" Action="Warning" />
<Rule Id="CA2231" Action="Warning" />
<Rule Id="CA2232" Action="Warning" />
<Rule Id="CA2235" Action="Warning" />
<Rule Id="CA2236" Action="Warning" />
<Rule Id="CA2237" Action="Warning" />
<Rule Id="CA2238" Action="Warning" />
<Rule Id="CA2240" Action="Warning" />
<Rule Id="CA2241" Action="Warning" />
<Rule Id="CA2242" Action="Warning" />
</Rules>
<Rules AnalyzerId="RefactoringEssentials" RuleNamespace="RefactoringEssentials">
<Rule Id="CS0126ReturnMustBeFollowedByAnyExpression" Action="None" />
<Rule Id="CS0169FieldIsNeverUsedAnalyzer" Action="None" />
<Rule Id="CS0183ExpressionIsAlwaysOfProvidedTypeAnalyzer" Action="None" />
<Rule Id="CS0618UsageOfObsoleteMemberAnalyzer" Action="None" />
<Rule Id="CS1573ParameterHasNoMatchingParamTagAnalyzer" Action="None" />
<Rule Id="CS1717AssignmentMadeToSameVariableAnalyzer" Action="None" />
<Rule Id="CS1729TypeHasNoConstructorWithNArgumentsAnalyzer" Action="None" />
<Rule Id="InconsistentNaming" Action="None" />
<Rule Id="ProhibitedModifiersAnalyzer" Action="None" />
<Rule Id="RECS0001" Action="Info" />
<Rule Id="RECS0091" Action="Hidden" />
<Rule Id="RECS0113" Action="Hidden" />
</Rules>
</RuleSet>

12
ICSharpCode.Decompiler/IL/Transforms/BlockTransform.cs

@ -22,7 +22,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms
public class BlockTransformContext : ILTransformContext public class BlockTransformContext : ILTransformContext
{ {
/// <summary> /// <summary>
/// The container currently being processed. /// The function containing the block currently being processed.
/// </summary>
public ILFunction Function { get; set; }
/// <summary>
/// The container containing the block currently being processed.
/// </summary> /// </summary>
public BlockContainer Container { get; set; } public BlockContainer Container { get; set; }
@ -72,6 +77,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
public void Run(ILFunction function, ILTransformContext context) public void Run(ILFunction function, ILTransformContext context)
{ {
var blockContext = new BlockTransformContext(context); var blockContext = new BlockTransformContext(context);
blockContext.Function = function;
foreach (var container in function.Descendants.OfType<BlockContainer>()) { foreach (var container in function.Descendants.OfType<BlockContainer>()) {
context.CancellationToken.ThrowIfCancellationRequested(); context.CancellationToken.ThrowIfCancellationRequested();
var cfg = LoopDetection.BuildCFG(container); var cfg = LoopDetection.BuildCFG(container);
@ -100,11 +106,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms
context.ControlFlowNode = cfgNode; context.ControlFlowNode = cfgNode;
context.Block = block; context.Block = block;
context.Block.CheckInvariant(ILPhase.Normal); block.CheckInvariant(ILPhase.Normal);
foreach (var transform in blockTransforms) { foreach (var transform in blockTransforms) {
context.CancellationToken.ThrowIfCancellationRequested(); context.CancellationToken.ThrowIfCancellationRequested();
transform.Run(context.Block, context); transform.Run(context.Block, context);
context.Block.CheckInvariant(ILPhase.Normal); block.CheckInvariant(ILPhase.Normal);
} }
context.Stepper.EndGroup(); context.Stepper.EndGroup();
} }

58
ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs

@ -29,41 +29,39 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// then we can replace the variable with the argument. /// then we can replace the variable with the argument.
/// 2) assignments of address-loading instructions to local variables /// 2) assignments of address-loading instructions to local variables
/// </summary> /// </summary>
public class CopyPropagation : IILTransform public class CopyPropagation : IBlockTransform
{ {
public void Run(ILFunction function, ILTransformContext context) public void Run(Block block, BlockTransformContext context)
{ {
foreach (var block in function.Descendants.OfType<Block>()) { for (int i = 0; i < block.Instructions.Count; i++) {
for (int i = 0; i < block.Instructions.Count; i++) { ILVariable v;
ILVariable v; ILInstruction copiedExpr;
ILInstruction copiedExpr; if (block.Instructions[i].MatchStLoc(out v, out copiedExpr)) {
if (block.Instructions[i].MatchStLoc(out v, out copiedExpr)) { if (v.IsSingleDefinition && CanPerformCopyPropagation(v, copiedExpr)) {
if (v.IsSingleDefinition && CanPerformCopyPropagation(v, copiedExpr)) { // un-inline the arguments of the ldArg instruction
// un-inline the arguments of the ldArg instruction ILVariable[] uninlinedArgs = new ILVariable[copiedExpr.Children.Count];
ILVariable[] uninlinedArgs = new ILVariable[copiedExpr.Children.Count]; for (int j = 0; j < uninlinedArgs.Length; j++) {
for (int j = 0; j < uninlinedArgs.Length; j++) { var arg = copiedExpr.Children[j];
var arg = copiedExpr.Children[j]; var type = context.TypeSystem.Compilation.FindType(arg.ResultType.ToKnownTypeCode());
var type = context.TypeSystem.Compilation.FindType(arg.ResultType.ToKnownTypeCode()); uninlinedArgs[j] = new ILVariable(VariableKind.StackSlot, type, arg.ResultType, arg.ILRange.Start) {
uninlinedArgs[j] = new ILVariable(VariableKind.StackSlot, type, arg.ResultType, arg.ILRange.Start) { Name = "C_" + arg.ILRange.Start
Name = "C_" + arg.ILRange.Start };
}; block.Instructions.Insert(i++, new StLoc(uninlinedArgs[j], arg));
block.Instructions.Insert(i++, new StLoc(uninlinedArgs[j], arg)); }
} v.Scope.Variables.AddRange(uninlinedArgs);
v.Scope.Variables.AddRange(uninlinedArgs); // perform copy propagation:
// perform copy propagation: foreach (var expr in v.Scope.Descendants) {
foreach (var expr in v.Scope.Descendants) { if (expr.MatchLdLoc(v)) {
if (expr.MatchLdLoc(v)) { var clone = copiedExpr.Clone();
var clone = copiedExpr.Clone(); for (int j = 0; j < uninlinedArgs.Length; j++) {
for (int j = 0; j < uninlinedArgs.Length; j++) { clone.Children[j].ReplaceWith(new LdLoc(uninlinedArgs[j]));
clone.Children[j].ReplaceWith(new LdLoc(uninlinedArgs[j]));
}
expr.ReplaceWith(clone);
} }
expr.ReplaceWith(clone);
} }
block.Instructions.RemoveAt(i);
int c = new ILInlining().InlineInto(block, i, aggressive: false);
i -= c + 1;
} }
block.Instructions.RemoveAt(i);
int c = new ILInlining().InlineInto(block, i, aggressive: false);
i -= c + 1;
} }
} }
} }

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

@ -30,14 +30,14 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// <remarks> /// <remarks>
/// Should run after inlining so that the expression patterns can be detected. /// Should run after inlining so that the expression patterns can be detected.
/// </remarks> /// </remarks>
public class ExpressionTransforms : ILVisitor, IILTransform public class ExpressionTransforms : ILVisitor, IBlockTransform
{ {
ILTransformContext context; ILTransformContext context;
void IILTransform.Run(ILFunction function, ILTransformContext context) public void Run(Block block, BlockTransformContext context)
{ {
this.context = context; this.context = context;
function.AcceptVisitor(this); Default(block);
} }
protected override void Default(ILInstruction inst) protected override void Default(ILInstruction inst)
@ -46,7 +46,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms
child.AcceptVisitor(this); child.AcceptVisitor(this);
} }
} }
protected internal override void VisitBlock(Block block)
{
// Don't visit child blocks; since this is a block transform
// we know those were already handled previously.
}
protected internal override void VisitComp(Comp inst) protected internal override void VisitComp(Comp inst)
{ {
base.VisitComp(inst); base.VisitComp(inst);

10
ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs

@ -29,7 +29,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// <summary> /// <summary>
/// Performs inlining transformations. /// Performs inlining transformations.
/// </summary> /// </summary>
public class ILInlining : IILTransform public class ILInlining : IILTransform, IBlockTransform
{ {
public void Run(ILFunction function, ILTransformContext context) public void Run(ILFunction function, ILTransformContext context)
{ {
@ -39,6 +39,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms
function.Variables.RemoveDead(); function.Variables.RemoveDead();
} }
public void Run(Block block, BlockTransformContext context)
{
InlineAllInBlock(block);
}
public bool InlineAllInBlock(Block block) public bool InlineAllInBlock(Block block)
{ {
bool modified = false; bool modified = false;
@ -312,13 +317,14 @@ namespace ICSharpCode.Decompiler.IL.Transforms
else else
return false; // abort, inlining not possible return false; // abort, inlining not possible
} }
/// <summary> /// <summary>
/// Determines whether it is safe to move 'expressionBeingMoved' past 'expr' /// Determines whether it is safe to move 'expressionBeingMoved' past 'expr'
/// </summary> /// </summary>
static bool IsSafeForInlineOver(ILInstruction expr, ILInstruction expressionBeingMoved) static bool IsSafeForInlineOver(ILInstruction expr, ILInstruction expressionBeingMoved)
{ {
return SemanticHelper.MayReorder(expressionBeingMoved, expr); return SemanticHelper.MayReorder(expressionBeingMoved, expr);
} }
} }
} }

22
ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs

@ -28,20 +28,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// Transforms array initialization pattern of System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray. /// Transforms array initialization pattern of System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray.
/// For collection and object initializers see <see cref="TransformInitializers"/> /// For collection and object initializers see <see cref="TransformInitializers"/>
/// </summary> /// </summary>
public class TransformArrayInitializers : IILTransform public class TransformArrayInitializers : IBlockTransform
{ {
ILTransformContext context; BlockTransformContext context;
ILFunction function;
void IILTransform.Run(ILFunction function, ILTransformContext context) void IBlockTransform.Run(Block block, BlockTransformContext context)
{ {
this.context = context; this.context = context;
this.function = function; for (int i = block.Instructions.Count - 1; i >= 0; i--) {
foreach (var block in function.Descendants.OfType<Block>()) { if (!DoTransform(block, i))
for (int i = block.Instructions.Count - 1; i >= 0; i--) { DoTransformMultiDim(block, i);
if (!DoTransform(block, i))
DoTransformMultiDim(block, i);
}
} }
} }
@ -58,7 +54,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
ILInstruction[] values; ILInstruction[] values;
int initArrayPos; int initArrayPos;
if (ForwardScanInitializeArrayRuntimeHelper(body, pos + 1, v, elementType, arrayLength, out values, out initArrayPos)) { if (ForwardScanInitializeArrayRuntimeHelper(body, pos + 1, v, elementType, arrayLength, out values, out initArrayPos)) {
var tempStore = function.RegisterVariable(VariableKind.StackSlot, v.Type); var tempStore = context.Function.RegisterVariable(VariableKind.StackSlot, v.Type);
var block = BlockFromInitializer(tempStore, elementType, arrayLength, values); var block = BlockFromInitializer(tempStore, elementType, arrayLength, values);
body.Instructions[pos].ReplaceWith(new StLoc(v, block)); body.Instructions[pos].ReplaceWith(new StLoc(v, block));
body.Instructions.RemoveAt(initArrayPos); body.Instructions.RemoveAt(initArrayPos);
@ -70,7 +66,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
int instructionsToRemove; int instructionsToRemove;
if (HandleSimpleArrayInitializer(body, pos + 1, v, arrayLength[0], out finalStore, out values, out instructionsToRemove)) { if (HandleSimpleArrayInitializer(body, pos + 1, v, arrayLength[0], out finalStore, out values, out instructionsToRemove)) {
var block = new Block(BlockType.ArrayInitializer); var block = new Block(BlockType.ArrayInitializer);
var tempStore = function.RegisterVariable(VariableKind.StackSlot, v.Type); var tempStore = context.Function.RegisterVariable(VariableKind.StackSlot, v.Type);
block.Instructions.Add(new StLoc(tempStore, new NewArr(elementType, arrayLength.Select(l => new LdcI4(l)).ToArray()))); block.Instructions.Add(new StLoc(tempStore, new NewArr(elementType, arrayLength.Select(l => new LdcI4(l)).ToArray())));
block.Instructions.AddRange(values.SelectWithIndex( block.Instructions.AddRange(values.SelectWithIndex(
(i, value) => { (i, value) => {
@ -88,7 +84,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
} }
if (HandleJaggedArrayInitializer(body, pos + 1, v, arrayLength[0], out finalStore, out values, out instructionsToRemove)) { if (HandleJaggedArrayInitializer(body, pos + 1, v, arrayLength[0], out finalStore, out values, out instructionsToRemove)) {
var block = new Block(BlockType.ArrayInitializer); var block = new Block(BlockType.ArrayInitializer);
var tempStore = function.RegisterVariable(VariableKind.StackSlot, v.Type); var tempStore = context.Function.RegisterVariable(VariableKind.StackSlot, v.Type);
block.Instructions.Add(new StLoc(tempStore, new NewArr(elementType, arrayLength.Select(l => new LdcI4(l)).ToArray()))); block.Instructions.Add(new StLoc(tempStore, new NewArr(elementType, arrayLength.Select(l => new LdcI4(l)).ToArray())));
block.Instructions.AddRange(values.SelectWithIndex((i, value) => StElem(new LdLoc(tempStore), new[] { new LdcI4(i) }, value, elementType))); block.Instructions.AddRange(values.SelectWithIndex((i, value) => StElem(new LdLoc(tempStore), new[] { new LdcI4(i) }, value, elementType)));
block.FinalInstruction = new LdLoc(tempStore); block.FinalInstruction = new LdLoc(tempStore);

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

@ -27,32 +27,30 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// <summary> /// <summary>
/// Description of TransformAssignment. /// Description of TransformAssignment.
/// </summary> /// </summary>
public class TransformAssignment : IILTransform public class TransformAssignment : IBlockTransform
{ {
ILTransformContext context; BlockTransformContext context;
void IILTransform.Run(ILFunction function, ILTransformContext context) void IBlockTransform.Run(Block block, BlockTransformContext context)
{ {
this.context = context; this.context = context;
foreach (var block in function.Descendants.OfType<Block>()) { for (int i = block.Instructions.Count - 1; i >= 0; i--) {
for (int i = block.Instructions.Count - 1; i >= 0; i--) { if (TransformPostIncDecOperatorOnAddress(block, i) || TransformPostIncDecOnStaticField(block, i) || TransformCSharp4PostIncDecOperatorOnAddress(block, i)) {
if (TransformPostIncDecOperatorOnAddress(block, i) || TransformPostIncDecOnStaticField(block, i) || TransformCSharp4PostIncDecOperatorOnAddress(block, i)) { block.Instructions.RemoveAt(i);
block.Instructions.RemoveAt(i); continue;
continue;
}
if (InlineLdAddressUsages(block, i)) {
block.Instructions.RemoveAt(i);
continue;
}
if (TransformPostIncDecOperator(block, i, function)) {
block.Instructions.RemoveAt(i);
continue;
}
if (TransformInlineAssignmentStObj(block, i))
continue;
if (TransformInlineAssignmentCall(block, i))
continue;
} }
if (InlineLdAddressUsages(block, i)) {
block.Instructions.RemoveAt(i);
continue;
}
if (TransformPostIncDecOperator(block, i)) {
block.Instructions.RemoveAt(i);
continue;
}
if (TransformInlineAssignmentStObj(block, i))
continue;
if (TransformInlineAssignmentCall(block, i))
continue;
} }
} }
@ -219,7 +217,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// final: ldloc s2 /// final: ldloc s2
/// }) /// })
/// </code> /// </code>
static bool TransformPostIncDecOperator(Block block, int i, ILFunction function) bool TransformPostIncDecOperator(Block block, int i)
{ {
var inst = block.Instructions[i] as StLoc; var inst = block.Instructions[i] as StLoc;
var nextInst = block.Instructions.ElementAtOrDefault(i + 1) as StLoc; var nextInst = block.Instructions.ElementAtOrDefault(i + 1) as StLoc;
@ -230,7 +228,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false; return false;
if ((binary.Operator != BinaryNumericOperator.Add && binary.Operator != BinaryNumericOperator.Sub) || !binary.Left.MatchLdLoc(inst.Variable) || !binary.Right.MatchLdcI4(1)) if ((binary.Operator != BinaryNumericOperator.Add && binary.Operator != BinaryNumericOperator.Sub) || !binary.Left.MatchLdLoc(inst.Variable) || !binary.Right.MatchLdcI4(1))
return false; return false;
var tempStore = function.RegisterVariable(VariableKind.StackSlot, inst.Variable.Type); var tempStore = context.Function.RegisterVariable(VariableKind.StackSlot, inst.Variable.Type);
var assignment = new Block(BlockType.CompoundOperator); var assignment = new Block(BlockType.CompoundOperator);
assignment.Instructions.Add(new StLoc(tempStore, new LdLoc(nextInst.Variable))); assignment.Instructions.Add(new StLoc(tempStore, new LdLoc(nextInst.Variable)));
assignment.Instructions.Add(new StLoc(nextInst.Variable, new BinaryNumericInstruction(binary.Operator, new LdLoc(tempStore), new LdcI4(1), binary.CheckForOverflow, binary.Sign))); assignment.Instructions.Add(new StLoc(nextInst.Variable, new BinaryNumericInstruction(binary.Operator, new LdLoc(tempStore), new LdcI4(1), binary.CheckForOverflow, binary.Sign)));

3
ICSharpCode.Decompiler/Properties/AssemblyInfo.template.cs

@ -30,6 +30,3 @@ using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("Microsoft.Usage", "CA2243:AttributeStringLiteralsShouldParseCorrectly", [assembly: SuppressMessage("Microsoft.Usage", "CA2243:AttributeStringLiteralsShouldParseCorrectly",
Justification = "AssemblyInformationalVersion does not need to be a parsable version")] Justification = "AssemblyInformationalVersion does not need to be a parsable version")]
[assembly: SuppressMessage("Language Usage Opportunities", "RECS0091:Use 'var' keyword when possible")]
[assembly: SuppressMessage("Redundancies in Code", "RECS0113:Redundant comma in array initializer")]

6
ICSharpCode.Decompiler/Tests/RoundtripAssembly.cs

@ -44,11 +44,7 @@ namespace ICSharpCode.Decompiler.Tests
[Test] [Test]
public void NewtonsoftJson_net40() public void NewtonsoftJson_net40()
{ {
try { RunWithTest("Newtonsoft.Json-net40", "Newtonsoft.Json.dll", "Newtonsoft.Json.Tests.dll");
RunWithTest("Newtonsoft.Json-net40", "Newtonsoft.Json.dll", "Newtonsoft.Json.Tests.dll");
} catch (CompilationFailedException) {
Assert.Ignore("Known bug in lambda decompilation");
}
} }
[Test] [Test]

1
ILSpy/ILSpy.csproj

@ -58,6 +58,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>false</Prefer32Bit>
<UseVSHostingProcess>false</UseVSHostingProcess> <UseVSHostingProcess>false</UseVSHostingProcess>
<CodeAnalysisRuleSet>..\ICSharpCode.Decompiler\ICSharpCode.Decompiler.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>false</Prefer32Bit>

2
ILSpy/Properties/AssemblyInfo.template.cs

@ -33,8 +33,6 @@ using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("Microsoft.Usage", "CA2243:AttributeStringLiteralsShouldParseCorrectly", [assembly: SuppressMessage("Microsoft.Usage", "CA2243:AttributeStringLiteralsShouldParseCorrectly",
Justification = "AssemblyInformationalVersion does not need to be a parsable version")] Justification = "AssemblyInformationalVersion does not need to be a parsable version")]
[assembly: SuppressMessage("Language Usage Opportunities", "RECS0091:Use 'var' keyword when possible")]
[assembly: SuppressMessage("Redundancies in Code", "RECS0113:Redundant comma in array initializer")]
[assembly: SuppressMessage("Redundancies in Symbol Declarations", "RECS0122:Initializing field with default value is redundant", [assembly: SuppressMessage("Redundancies in Symbol Declarations", "RECS0122:Initializing field with default value is redundant",
Justification = "Explicit default initialization is necessary to avoid compiler warning with MEF")] Justification = "Explicit default initialization is necessary to avoid compiler warning with MEF")]

Loading…
Cancel
Save