Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Cecil.Decompiler improvements #1

Open
wants to merge 7 commits into from

2 participants

@chkn
Owner

Hi,
Miguel's recent blog post about Cecil.Decompiler reminded me that I'd hacked on it a bit recently. Hope these modest changes are helpful to anyone.
-Alex

@chkn chkn Implement decompiling of DelegateCreationExpression and DelegateInvoc…
…ationExpression. Other minor bugfixes and touchups.
4ee8f71
@jbevain

This should call a OnConstrained for consistency.

@jbevain

This looks fishy, and likely to break the this case.

Owner

I couldn't figure out what the +1 was for, and I think it was breaking static methods. Looking at PushArgumentReference, it is expecting "this" to be index == 0 if method.HasThis. With the change, that seems correct to me.

@jbevain

I think this should not be here. We should rather create a MethodAddressExpression { IsVirtual = t } in ldftn and ldvftn, later to be transformed in a DelegateCreationExpression by a transformer step.

@jbevain
Collaborator

I've added inline comments, but this is looking good. Some tests would be cool. Thanks!

@chkn
Owner

Thanks for reviewing this so quickly! I think I addressed all your comments. I got the test suite running and most everything passes, except for a couple tests where the comparison is reversed in the ternary (though the code is still equivalent to the original). I'm not very experienced at writing tests, but I gave it a shot writing one for the new delegate functionality. Let me know if there's anything else I can do to help get this committed. Thanks again!

@jbevain

Is this actually generated? I don't see modifications to the code generator.

@jbevain
Collaborator

This is looking good. Just make sure the code generator is modified to properly generate MethodAddressExpression and we'll get that in.

@chkn
Owner

Is this correct? My boo environment is giving me trouble

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 6, 2011
  1. @chkn

    Implement decompiling of DelegateCreationExpression and DelegateInvoc…

    chkn authored
    …ationExpression. Other minor bugfixes and touchups.
Commits on Feb 8, 2011
  1. @chkn
  2. @chkn

    Add OnConstrained method.

    chkn authored
Commits on Feb 10, 2011
  1. @chkn
Commits on Feb 19, 2011
  1. @chkn

    Make pipeline steps public to enable external consumers to build thei…

    chkn authored
    …r own pipelines/languages.
Commits on Feb 25, 2011
  1. @chkn

    Update code generator

    chkn authored
  2. @chkn
This page is out of date. Refresh to see the latest.
Showing with 380 additions and 30 deletions.
  1. +5 −0 decompiler/Cecil.Decompiler.Tests/Cecil.Decompiler.CSharp/MethodCalls.cs
  2. +1 −0  decompiler/Cecil.Decompiler.Tests/Cecil.Decompiler.Tests.csproj
  3. +1 −1  decompiler/Cecil.Decompiler.Tests/Cecil.Decompiler/Addin.cs
  4. +4 −3 decompiler/Cecil.Decompiler.Tests/Cecil.Decompiler/DecompilerTestFixture.cs
  5. +7 −0 decompiler/Cecil.Decompiler.Tests/TestCases/CSharp/MethodCalls.Delegates.txt
  6. +8 −0 decompiler/Cecil.Decompiler.Tests/TestCases/CSharp/MethodCalls.cs
  7. +8 −0 decompiler/Cecil.Decompiler/Cecil.Decompiler.Ast/BaseCodeTransformer.cs
  8. +8 −0 decompiler/Cecil.Decompiler/Cecil.Decompiler.Ast/BaseCodeVisitor.cs
  9. +2 −1  decompiler/Cecil.Decompiler/Cecil.Decompiler.Ast/CodeNodeType.cs
  10. +2 −1  decompiler/Cecil.Decompiler/Cecil.Decompiler.Ast/ICodeTransformer.cs
  11. +2 −1  decompiler/Cecil.Decompiler/Cecil.Decompiler.Ast/ICodeVisitor.cs
  12. +80 −0 decompiler/Cecil.Decompiler/Cecil.Decompiler.Ast/MethodAddressExpression.cs
  13. +6 −1 decompiler/Cecil.Decompiler/Cecil.Decompiler.Cil/BaseInstructionVisitor.cs
  14. +2 −1  decompiler/Cecil.Decompiler/Cecil.Decompiler.Cil/IInstructionVisitor.cs
  15. +3 −0  decompiler/Cecil.Decompiler/Cecil.Decompiler.Cil/InstructionDispatcher.cs
  16. +4 −0 decompiler/Cecil.Decompiler/Cecil.Decompiler.Languages/CSharp.cs
  17. +32 −2 decompiler/Cecil.Decompiler/Cecil.Decompiler.Languages/CSharpWriter.cs
  18. +67 −0 decompiler/Cecil.Decompiler/Cecil.Decompiler.Steps/DelegateCreateStep.cs
  19. +68 −0 decompiler/Cecil.Decompiler/Cecil.Decompiler.Steps/DelegateInvokeStep.cs
  20. +1 −1  decompiler/Cecil.Decompiler/Cecil.Decompiler.Steps/OperatorStep.cs
  21. +1 −1  decompiler/Cecil.Decompiler/Cecil.Decompiler.Steps/RebuildForStatements.cs
  22. +1 −1  decompiler/Cecil.Decompiler/Cecil.Decompiler.Steps/RebuildForeachStatements.cs
  23. +3 −0  decompiler/Cecil.Decompiler/Cecil.Decompiler.Steps/RemoveLastReturn.cs
  24. +1 −1  decompiler/Cecil.Decompiler/Cecil.Decompiler.Steps/SelfAssignment.cs
  25. +1 −1  decompiler/Cecil.Decompiler/Cecil.Decompiler.Steps/TypeOfStep.cs
  26. +5 −2 decompiler/Cecil.Decompiler/Cecil.Decompiler.csproj
  27. +1 −1  decompiler/Cecil.Decompiler/Cecil.Decompiler/Annotations.cs
  28. +25 −5 decompiler/Cecil.Decompiler/Cecil.Decompiler/ExpressionDecompiler.cs
  29. +7 −0 decompiler/Cecil.Decompiler/Cecil.Decompiler/Extensions.cs
  30. +18 −6 decompiler/Cecil.Decompiler/Cecil.Decompiler/StatementDecompiler.cs
  31. +5 −0 decompiler/CodeGen/CodeStructureModel.boo
  32. +1 −0  decompiler/CodeGen/instructions.txt
View
5 decompiler/Cecil.Decompiler.Tests/Cecil.Decompiler.CSharp/MethodCalls.cs
@@ -28,5 +28,10 @@ public void CallIgnoreReturnValue ()
public void ArrayLength ()
{
}
+
+ [CSharp]
+ public void Delegates ()
+ {
+ }
}
}
View
1  decompiler/Cecil.Decompiler.Tests/Cecil.Decompiler.Tests.csproj
@@ -170,6 +170,7 @@
<None Include="TestCases\ControlFlow\TernaryExpression.il" />
<None Include="TestCases\ControlFlow\ThreeReturns.il" />
<None Include="TestCases\ControlFlow\TwoIfs.il" />
+ <None Include="TestCases\CSharp\MethodCalls.Delegates.txt" />
</ItemGroup>
<ItemGroup>
<Content Include="TestCases\ControlFlow\BoolAndGreaterOrEqualThan-cfg.txt" />
View
2  decompiler/Cecil.Decompiler.Tests/Cecil.Decompiler/Addin.cs
@@ -263,7 +263,7 @@ string DecompileMethod (MethodDefinition method)
AssemblyDefinition GetAssembly (CompilerResults result)
{
- return AssemblyFactory.GetAssembly (result.PathToAssembly);
+ return AssemblyDefinition.ReadAssembly (result.PathToAssembly);
}
MethodDefinition GetMethod (AssemblyDefinition assembly)
View
7 decompiler/Cecil.Decompiler.Tests/Cecil.Decompiler/DecompilerTestFixture.cs
@@ -24,6 +24,7 @@
#endregion
using System;
+using System.Linq;
using System.Diagnostics;
using System.IO;
using Mono.Cecil;
@@ -78,10 +79,10 @@ protected MethodDefinition LoadTestCaseMethod (string testCaseName)
{
CompileTestCase (testCaseName);
- AssemblyDefinition assembly = AssemblyFactory.GetAssembly (TestAssemblyPath);
- TypeDefinition type = assembly.MainModule.Types ["TestCase"];
+ AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly (TestAssemblyPath);
+ TypeDefinition type = assembly.MainModule.Types.Single (t => t.Name == "TestCase");
Assert.IsNotNull (type, "Type TestCase not found!");
- MethodDefinition[] found = type.Methods.GetMethod ("Main");
+ MethodDefinition[] found = type.Methods.Where (m => m.Name == "Main").ToArray ();
Assert.AreEqual (1, found.Length, "Method TestCase.Main not found!");
return found [0];
}
View
7 decompiler/Cecil.Decompiler.Tests/TestCases/CSharp/MethodCalls.Delegates.txt
@@ -0,0 +1,7 @@
+public void Delegates()
+{
+ Test V_0;
+ V_0 = new Test(this.Foo);
+ V_0("a", "b", "c");
+ return;
+}
View
8 decompiler/Cecil.Decompiler.Tests/TestCases/CSharp/MethodCalls.cs
@@ -1,5 +1,7 @@
using System;
+delegate void Test (string a, string b, string c);
+
class Program {
public void Foo ()
@@ -39,4 +41,10 @@ public int ArrayLength (int [] integers)
{
return integers.Length;
}
+
+ public void Delegates ()
+ {
+ Test foo = new Test (this.Foo);
+ foo ("a", "b", "c");
+ }
}
View
8 decompiler/Cecil.Decompiler/Cecil.Decompiler.Ast/BaseCodeTransformer.cs
@@ -83,6 +83,8 @@ public virtual ICodeNode Visit (ICodeNode node)
return VisitMethodInvocationExpression ((MethodInvocationExpression) node);
case CodeNodeType.MethodReferenceExpression:
return VisitMethodReferenceExpression ((MethodReferenceExpression) node);
+ case CodeNodeType.MethodAddressExpression:
+ return VisitMethodAddressExpression ((MethodAddressExpression) node);
case CodeNodeType.DelegateCreationExpression:
return VisitDelegateCreationExpression ((DelegateCreationExpression) node);
case CodeNodeType.DelegateInvocationExpression:
@@ -323,6 +325,12 @@ public virtual ICodeNode VisitMethodReferenceExpression (MethodReferenceExpressi
{
node.Target = (Expression) Visit (node.Target);
return node;
+ }
+
+ public virtual ICodeNode VisitMethodAddressExpression (MethodAddressExpression node)
+ {
+ node.Target = (Expression) Visit (node.Target);
+ return node;
}
public virtual ICodeNode VisitDelegateCreationExpression (DelegateCreationExpression node)
View
8 decompiler/Cecil.Decompiler/Cecil.Decompiler.Ast/BaseCodeVisitor.cs
@@ -103,6 +103,9 @@ public virtual void Visit (ICodeNode node)
case CodeNodeType.MethodReferenceExpression:
VisitMethodReferenceExpression ((MethodReferenceExpression) node);
break;
+ case CodeNodeType.MethodAddressExpression:
+ VisitMethodAddressExpression ((MethodAddressExpression) node);
+ break;
case CodeNodeType.DelegateCreationExpression:
VisitDelegateCreationExpression ((DelegateCreationExpression) node);
break;
@@ -305,6 +308,11 @@ public virtual void VisitMethodInvocationExpression (MethodInvocationExpression
public virtual void VisitMethodReferenceExpression (MethodReferenceExpression node)
{
Visit (node.Target);
+ }
+
+ public virtual void VisitMethodAddressExpression (MethodAddressExpression node)
+ {
+ Visit (node.Target);
}
public virtual void VisitDelegateCreationExpression (DelegateCreationExpression node)
View
3  decompiler/Cecil.Decompiler/Cecil.Decompiler.Ast/CodeNodeType.cs
@@ -48,7 +48,8 @@ public enum CodeNodeType {
SwitchStatement,
CatchClause,
TryStatement,
- BlockExpression,
+ BlockExpression,
+ MethodAddressExpression,
MethodInvocationExpression,
MethodReferenceExpression,
DelegateCreationExpression,
View
3  decompiler/Cecil.Decompiler/Cecil.Decompiler.Ast/ICodeTransformer.cs
@@ -50,7 +50,8 @@ public interface ICodeTransformer {
ICodeNode VisitTryStatement (TryStatement node);
ICodeNode VisitBlockExpression (BlockExpression node);
ICodeNode VisitMethodInvocationExpression (MethodInvocationExpression node);
- ICodeNode VisitMethodReferenceExpression (MethodReferenceExpression node);
+ ICodeNode VisitMethodReferenceExpression (MethodReferenceExpression node);
+ ICodeNode VisitMethodAddressExpression (MethodAddressExpression node);
ICodeNode VisitDelegateCreationExpression (DelegateCreationExpression node);
ICodeNode VisitDelegateInvocationExpression (DelegateInvocationExpression node);
ICodeNode VisitLiteralExpression (LiteralExpression node);
View
3  decompiler/Cecil.Decompiler/Cecil.Decompiler.Ast/ICodeVisitor.cs
@@ -50,7 +50,8 @@ public interface ICodeVisitor {
void VisitTryStatement (TryStatement node);
void VisitBlockExpression (BlockExpression node);
void VisitMethodInvocationExpression (MethodInvocationExpression node);
- void VisitMethodReferenceExpression (MethodReferenceExpression node);
+ void VisitMethodReferenceExpression (MethodReferenceExpression node);
+ void VisitMethodAddressExpression (MethodAddressExpression node);
void VisitDelegateCreationExpression (DelegateCreationExpression node);
void VisitDelegateInvocationExpression (DelegateInvocationExpression node);
void VisitLiteralExpression (LiteralExpression node);
View
80 decompiler/Cecil.Decompiler/Cecil.Decompiler.Ast/MethodAddressExpression.cs
@@ -0,0 +1,80 @@
+#region license
+//
+// (C) 2005 - 2007 db4objects Inc. http://www.db4o.com
+// (C) 2007 - 2008 Novell, Inc. http://www.novell.com
+// (C) 2007 - 2008 Jb Evain http://evain.net
+//
+// 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.
+//
+#endregion
+
+// Warning: generated do not edit
+
+using System;
+using System.Collections.Generic;
+
+using Mono.Cecil;
+using Mono.Cecil.Cil;
+
+namespace Cecil.Decompiler.Ast {
+
+ public class MethodAddressExpression : Expression {
+
+ Expression target;
+ bool is_virtual;
+ MethodReference method;
+
+ public MethodAddressExpression ()
+ {
+ }
+
+ public MethodAddressExpression (MethodReference method)
+ {
+ this.method = method;
+ }
+
+ public Expression Target
+ {
+ get { return target; }
+ set { this.target = value; }
+ }
+
+ public MethodReference Method
+ {
+ get { return method; }
+ set { this.method = value; }
+ }
+
+ public bool IsVirtual
+ {
+ get { return is_virtual; }
+ set { this.is_virtual = value; }
+ }
+
+ public override CodeNodeType CodeNodeType
+ {
+ get { return CodeNodeType.MethodAddressExpression; }
+ }
+ }
+
+ public static partial class CodeNode {
+
+ }
+}
View
7 decompiler/Cecil.Decompiler/Cecil.Decompiler.Cil/BaseInstructionVisitor.cs
@@ -1007,7 +1007,12 @@ public virtual void OnRefanytype (Instruction instruction)
{
throw new NotImplementedException (Formatter.FormatInstruction (instruction));
}
-
+
+ public virtual void OnConstrained (Instruction instruction)
+ {
+ throw new NotImplementedException (Formatter.FormatInstruction (instruction));
+ }
+
public void Visit (Instruction instruction)
{
InstructionDispatcher.Dispatch (instruction, this);
View
3  decompiler/Cecil.Decompiler/Cecil.Decompiler.Cil/IInstructionVisitor.cs
@@ -226,6 +226,7 @@ interface IInstructionVisitor {
void OnInitblk (Instruction instruction);
void OnRethrow (Instruction instruction);
void OnSizeof (Instruction instruction);
- void OnRefanytype (Instruction instruction);
+ void OnRefanytype (Instruction instruction);
+ void OnConstrained (Instruction instruction);
}
}
View
3  decompiler/Cecil.Decompiler/Cecil.Decompiler.Cil/InstructionDispatcher.cs
@@ -645,6 +645,9 @@ public static void Dispatch (Instruction instruction, IInstructionVisitor visito
case Code.Refanytype:
visitor.OnRefanytype (instruction);
return;
+ case Code.Constrained:
+ visitor.OnConstrained (instruction);
+ return;
default:
throw new ArgumentException (Formatter.FormatInstruction (instruction), "instruction");
}
View
4 decompiler/Cecil.Decompiler/Cecil.Decompiler.Languages/CSharp.cs
@@ -46,6 +46,8 @@ public virtual DecompilationPipeline CreatePipeline ()
{
return new DecompilationPipeline (
new StatementDecompiler (BlockOptimization.Basic),
+ DelegateCreateStep.Instance,
+ DelegateInvokeStep.Instance,
TypeOfStep.Instance,
DeclareTopLevelVariables.Instance);
}
@@ -75,6 +77,8 @@ public override DecompilationPipeline CreatePipeline ()
{
return new DecompilationPipeline (
new StatementDecompiler (BlockOptimization.Detailed),
+ DelegateCreateStep.Instance,
+ DelegateInvokeStep.Instance,
RemoveLastReturn.Instance,
PropertyStep.Instance,
CanCastStep.Instance,
View
34 decompiler/Cecil.Decompiler/Cecil.Decompiler.Languages/CSharpWriter.cs
@@ -25,6 +25,7 @@
#endregion
using System;
+using System.Linq;
using System.Collections.Generic;
using System.Text;
@@ -150,7 +151,7 @@ public override void VisitVariableDeclarationExpression (VariableDeclarationExpr
WriteReference (variable.VariableType);
WriteSpace ();
- Write (variable.Name);
+ Write (string.IsNullOrEmpty (node.Variable.Name)? ("V_" + node.Variable.Index) : node.Variable.Name);
}
public override void VisitAssignExpression (AssignExpression node)
@@ -167,7 +168,7 @@ public override void VisitArgumentReferenceExpression (ArgumentReferenceExpressi
public override void VisitVariableReferenceExpression (VariableReferenceExpression node)
{
- Write (node.Variable.Name);
+ Write (string.IsNullOrEmpty (node.Variable.Name)? ("V_" + node.Variable.Index) : node.Variable.Name);
}
public override void VisitLiteralExpression (LiteralExpression node)
@@ -206,6 +207,14 @@ public override void VisitMethodInvocationExpression (MethodInvocationExpression
VisitList (node.Arguments);
WriteToken (")");
}
+
+ public override void VisitDelegateInvocationExpression (DelegateInvocationExpression node)
+ {
+ Visit (node.Target);
+ WriteToken ("(");
+ VisitList (node.Arguments);
+ WriteToken (")");
+ }
public override void VisitBlockExpression (BlockExpression node)
{
@@ -714,6 +723,27 @@ public override void VisitObjectCreationExpression (ObjectCreationExpression nod
Visit (node.Arguments);
WriteToken (")");
}
+
+ public override void VisitDelegateCreationExpression (DelegateCreationExpression node)
+ {
+ WriteKeyword ("new");
+ WriteSpace ();
+ WriteReference (node.Type);
+ WriteToken ("(");
+
+ if (node.Target != null) {
+ Visit (node.Target);
+ WriteToken (".");
+ }
+
+ if (!node.Method.HasThis) {
+ WriteReference (node.Method.DeclaringType);
+ WriteToken (".");
+ }
+
+ Write (node.Method.Name);
+ WriteToken (")");
+ }
public override void VisitPropertyReferenceExpression (PropertyReferenceExpression node)
{
View
67 decompiler/Cecil.Decompiler/Cecil.Decompiler.Steps/DelegateCreateStep.cs
@@ -0,0 +1,67 @@
+#region license
+//
+// (C) 2007 - 2008 Novell, Inc. http://www.novell.com
+// (C) 2007 - 2008 Jb Evain http://evain.net
+// (C) 2010 Alexander Corrado http://nirvanai.com
+//
+// 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.
+//
+#endregion
+
+using System;
+
+using Mono.Cecil.Cil;
+
+using Cecil.Decompiler.Ast;
+
+namespace Cecil.Decompiler.Steps {
+
+ public class DelegateCreateStep : BaseCodeTransformer, IDecompilationStep {
+
+ public static readonly IDecompilationStep Instance = new DelegateCreateStep ();
+
+ public override ICodeNode VisitObjectCreationExpression (ObjectCreationExpression node)
+ {
+ if (node.Constructor == null)
+ goto skip;
+
+ var type = node.Constructor.DeclaringType;
+
+ if (!type.Resolve ().IsDelegate ())
+ goto skip;
+
+ var target = node.Arguments [0];
+ var method = node.Arguments [1] as MethodAddressExpression;
+
+ if (method == null)
+ goto skip;
+
+ return new DelegateCreationExpression (type, method.Method, target);
+
+ skip:
+ return base.VisitObjectCreationExpression (node);
+ }
+
+ public BlockStatement Process (DecompilationContext context, BlockStatement body)
+ {
+ return (BlockStatement) VisitBlockStatement (body);
+ }
+ }
+}
View
68 decompiler/Cecil.Decompiler/Cecil.Decompiler.Steps/DelegateInvokeStep.cs
@@ -0,0 +1,68 @@
+#region license
+//
+// (C) 2007 - 2008 Novell, Inc. http://www.novell.com
+// (C) 2007 - 2008 Jb Evain http://evain.net
+// (C) 2010 Alexander Corrado http://nirvanai.com
+//
+// 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.
+//
+#endregion
+
+using System;
+
+using Mono.Cecil.Cil;
+
+using Cecil.Decompiler.Ast;
+
+namespace Cecil.Decompiler.Steps {
+
+ public class DelegateInvokeStep : BaseCodeTransformer, IDecompilationStep {
+
+ public static readonly IDecompilationStep Instance = new DelegateInvokeStep ();
+
+ public override ICodeNode VisitMethodInvocationExpression (MethodInvocationExpression node)
+ {
+ var method_ref = node.Method as MethodReferenceExpression;
+ if (method_ref == null)
+ goto skip;
+
+ var method = method_ref.Method;
+ if (method.Name != "Invoke")
+ goto skip;
+
+ if (!method.DeclaringType.Resolve ().IsDelegate ())
+ goto skip;
+
+ var invoke = new DelegateInvocationExpression (method_ref.Target);
+
+ invoke.Arguments = node.Arguments;
+
+ return invoke;
+
+ skip:
+ return base.VisitMethodInvocationExpression (node);
+ }
+
+ public BlockStatement Process (DecompilationContext context, BlockStatement body)
+ {
+ return (BlockStatement) VisitBlockStatement (body);
+ }
+ }
+}
View
2  decompiler/Cecil.Decompiler/Cecil.Decompiler.Steps/OperatorStep.cs
@@ -5,7 +5,7 @@
namespace Cecil.Decompiler.Steps {
- class OperatorStep : BaseCodeTransformer, IDecompilationStep {
+ public class OperatorStep : BaseCodeTransformer, IDecompilationStep {
public static readonly IDecompilationStep Instance = new OperatorStep();
View
2  decompiler/Cecil.Decompiler/Cecil.Decompiler.Steps/RebuildForStatements.cs
@@ -32,7 +32,7 @@
namespace Cecil.Decompiler.Steps {
- class RebuildForStatements : Ast.BaseCodeVisitor, IDecompilationStep {
+ public class RebuildForStatements : Ast.BaseCodeVisitor, IDecompilationStep {
public static readonly IDecompilationStep Instance = new RebuildForStatements ();
View
2  decompiler/Cecil.Decompiler/Cecil.Decompiler.Steps/RebuildForeachStatements.cs
@@ -6,7 +6,7 @@
namespace Cecil.Decompiler.Steps {
- internal class RebuildForeachStatements : Ast.BaseCodeVisitor, IDecompilationStep {
+ public class RebuildForeachStatements : Ast.BaseCodeVisitor, IDecompilationStep {
public static readonly IDecompilationStep Instance = new RebuildForeachStatements ();
View
3  decompiler/Cecil.Decompiler/Cecil.Decompiler.Steps/RemoveLastReturn.cs
@@ -37,6 +37,9 @@ public class RemoveLastReturn : IDecompilationStep {
public BlockStatement Process (DecompilationContext context, BlockStatement block)
{
var index = block.Statements.Count - 1;
+ if (index == -1)
+ return block;
+
var ret = block.Statements [index] as ReturnStatement;
if (ret == null)
return block;
View
2  decompiler/Cecil.Decompiler/Cecil.Decompiler.Steps/SelfAssignment.cs
@@ -67,7 +67,7 @@ public int GetHashCode (object obj)
}
}
- class SelfAssignement : BaseCodeTransformer, IDecompilationStep {
+ public class SelfAssignement : BaseCodeTransformer, IDecompilationStep {
public static readonly IDecompilationStep Instance = new SelfAssignement ();
View
2  decompiler/Cecil.Decompiler/Cecil.Decompiler.Steps/TypeOfStep.cs
@@ -32,7 +32,7 @@
namespace Cecil.Decompiler.Steps {
- class TypeOfStep : BaseCodeTransformer, IDecompilationStep {
+ public class TypeOfStep : BaseCodeTransformer, IDecompilationStep {
public static readonly IDecompilationStep Instance = new TypeOfStep ();
View
7 decompiler/Cecil.Decompiler/Cecil.Decompiler.csproj 100755 → 100644
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<ProductVersion>9.0.30729</ProductVersion>
@@ -170,7 +170,8 @@
<Compile Include="Cecil.Decompiler.Steps\Matcher.cs" />
<Compile Include="Cecil.Decompiler.Steps\RebuildForeachStatements.cs" />
<Compile Include="Cecil.Decompiler.Steps\RebuildForStatements.cs" />
- <Compile Include="Cecil.Decompiler.Steps\RemoveLastReturn.cs" />
+ <Compile Include="Cecil.Decompiler.Steps\RemoveLastReturn.cs" />
+ <Compile Include="Cecil.Decompiler.Steps\DelegateInvokeStep.cs" />
<Compile Include="Cecil.Decompiler\Annotations.cs" />
<Compile Include="Cecil.Decompiler\BlockOptimizations.cs" />
<Compile Include="Cecil.Decompiler\DecompilationContext.cs" />
@@ -179,6 +180,8 @@
<Compile Include="Cecil.Decompiler\Extensions.cs" />
<Compile Include="Cecil.Decompiler\StatementDecompiler.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Cecil.Decompiler.Ast\MethodAddressExpression.cs" />
+ <Compile Include="Cecil.Decompiler.Steps\DelegateCreateStep.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\mcs\class\Mono.Cecil\Mono.Cecil.csproj">
View
2  decompiler/Cecil.Decompiler/Cecil.Decompiler/Annotations.cs
@@ -448,7 +448,7 @@ protected override void ProcessMultipleWayBlock (InstructionBlock block)
Annotate (last, Annotation.Switch);
foreach (var target in targets)
- Annotate (target, Annotation.Labeled);
+ Labelize (target);
ProcessMultipleWayBlockSuccessors (block);
}
View
30 decompiler/Cecil.Decompiler/Cecil.Decompiler/ExpressionDecompiler.cs
@@ -205,8 +205,8 @@ public override void OnCall (Instruction instruction)
public override void OnNewobj (Instruction instruction)
{
- var constructor = (MethodReference) instruction.Operand;
-
+ var constructor = (MethodReference) instruction.Operand;
+
var arguments = PopRange (constructor.Parameters.Count);
var @new = new ObjectCreationExpression (constructor, null, null);
@@ -214,8 +214,26 @@ public override void OnNewobj (Instruction instruction)
AddRange (@new.Arguments, arguments);
Push (@new);
+ }
+
+ public override void OnLdftn (Instruction instruction)
+ {
+ var method = (MethodReference) instruction.Operand;
+
+ var addressof = new MethodAddressExpression (method);
+
+ Push (addressof);
}
-
+
+ public override void OnLdvirtftn (Instruction instruction)
+ {
+ var method = (MethodReference) instruction.Operand;
+
+ var addressof = new MethodAddressExpression (method) { IsVirtual = true, Target = Pop () };
+
+ Push (addressof);
+ }
+
public override void OnInitobj (Instruction instruction)
{
var address = (AddressOfExpression) Pop ();
@@ -882,12 +900,14 @@ public override void OnLdarg_3 (Instruction instruction)
public override void OnLdarg (Instruction instruction)
{
- PushArgumentReference (((ParameterDefinition) instruction.Operand).Index + 1);
+ var index = ((ParameterDefinition) instruction.Operand).Index;
+ PushArgumentReference (index);
}
public override void OnLdarga (Instruction instruction)
{
- PushArgumentReference (((ParameterDefinition) instruction.Operand).Index + 1);
+ var index = ((ParameterDefinition) instruction.Operand).Index;
+ PushArgumentReference (index);
PushAddressOf ();
}
View
7 decompiler/Cecil.Decompiler/Cecil.Decompiler/Extensions.cs
@@ -59,6 +59,13 @@ static BlockStatement RunPipeline (DecompilationPipeline pipeline, MethodBody bo
pipeline.Run (body);
return pipeline.Body;
}
+
+ public static bool IsDelegate(this TypeDefinition type)
+ {
+ return type.BaseType != null &&
+ (type.BaseType.FullName == "System.Delegate"
+ || type.BaseType.FullName == "System.MulticastDelegate");
+ }
internal static TElement First<TElement> (this IList<TElement> list)
{
View
24 decompiler/Cecil.Decompiler/Cecil.Decompiler/StatementDecompiler.cs
@@ -26,6 +26,7 @@
#endregion
using System;
+using System.Linq;
using System.Collections.Generic;
using Mono.Cecil;
@@ -220,10 +221,15 @@ void RemoveRegisterVariables ()
void CheckLabel (Instruction instruction)
{
+ current_label = GetLabelName (instruction) ?? current_label;
+ }
+
+ string GetLabelName (Instruction instruction)
+ {
if (!annotations.IsAnnotated (instruction, Annotation.Labeled))
- return;
+ return null;
- current_label = annotations.GetData<string> (instruction);
+ return annotations.GetData<string> (instruction);
}
bool SkipExceptionObjectAction (Instruction instruction)
@@ -455,11 +461,11 @@ void MoveStatementsToBlock (BlockRange range, BlockStatement block)
MoveStatementsToBlock (range.Start, range.End, block);
}
- /*
+
public override void OnSwitch (Instruction instruction)
{
- AddOptimizedSwitch (instruction);
-
+ //AddOptimizedSwitch (instruction);
+
var @switch = new SwitchStatement (Pop ());
var targets = (Instruction []) instruction.Operand;
@@ -479,7 +485,8 @@ public override void OnSwitch (Instruction instruction)
Add (@switch);
}
-
+
+ /*
void AddOptimizedSwitch (Instruction instruction)
{
RemoveSwitchTemporaryVariable ();
@@ -661,6 +668,7 @@ public override void OnBr (Instruction instruction)
return;
switch (annotation) {
+ case Annotation.Labeled:
case Annotation.Goto:
Add (new GotoStatement (annotations.GetData<string> (instruction)));
break;
@@ -688,6 +696,10 @@ public override void OnEndfinally (Instruction instruction)
public override void OnEndfilter (Instruction instruction)
{
}
+
+ public override void OnConstrained (Instruction instruction)
+ {
+ }
public override void OnStloc_0 (Instruction instruction)
{
View
5 decompiler/CodeGen/CodeStructureModel.boo
@@ -112,6 +112,11 @@ class MethodInvocationExpression (Expression):
class MethodReferenceExpression (Expression):
Target as Expression
Method as MethodReference
+
+class MethodAddressExpression (Expression):
+ Target as Expression
+ Method as MethodReference
+ IsVirtual as bool
class DelegateCreationExpression (Expression):
Type as TypeReference
View
1  decompiler/CodeGen/instructions.txt
@@ -193,3 +193,4 @@ initblk
rethrow
sizeof
refanytype
+constrained
Something went wrong with that request. Please try again.