Ejemplo n.º 1
0
        public void TestZeroMinusNumber()
        {
            var Node = (AstNode)ast.Binary(ast.Immediate(0), "-", ast.Argument <int>(0, "Arg"));

            Assert.AreEqual("(0 - Arg)", new GeneratorCSharp().GenerateRoot(Node).ToString());
            Node = new AstOptimizer().Optimize(Node);
            Assert.AreEqual("(-Arg)", new GeneratorCSharp().GenerateRoot(Node).ToString());
        }
Ejemplo n.º 2
0
        public void TestAddNegated()
        {
            var Node = (AstNode)ast.Binary(ast.Immediate(1), "+", -ast.Argument <int>(0, "Arg"));

            Assert.AreEqual("(1 + (-Arg))", new GeneratorCSharp().GenerateRoot(Node).ToString());
            Node = new AstOptimizer().Optimize(Node);
            Assert.AreEqual("(1 - Arg)", new GeneratorCSharp().GenerateRoot(Node).ToString());
        }
Ejemplo n.º 3
0
        public void TestCastToImmediate()
        {
            var Node = (AstNode)ast.Cast <uint>(ast.Immediate((int)7));

            Assert.AreEqual("((UInt32)7)", new GeneratorCSharp().GenerateRoot(Node).ToString());
            Node = new AstOptimizer().Optimize(Node);
            Assert.AreEqual("7", new GeneratorCSharp().GenerateRoot(Node).ToString());
        }
Ejemplo n.º 4
0
        public void TestCastSignExtend2()
        {
            var Node = (AstNode)ast.Cast <sbyte>(ast.Cast <uint>(ast.Argument <int>(0, "Arg")));

            Assert.AreEqual("((SByte)((UInt32)Arg))", new GeneratorCSharp().GenerateRoot(Node).ToString());
            Node = new AstOptimizer().Optimize(Node);
            Assert.AreEqual("((SByte)Arg)", new GeneratorCSharp().GenerateRoot(Node).ToString());
        }
Ejemplo n.º 5
0
        public void TestCalculateImmediates()
        {
            var Node = (AstNode)((ast.Immediate(0) + ast.Immediate(2)) * ast.Immediate(3));

            Assert.AreEqual("((0 + 2) * 3)", new GeneratorCSharp().GenerateRoot(Node).ToString());
            Node = new AstOptimizer().Optimize(Node);
            Assert.AreEqual("6", new GeneratorCSharp().GenerateRoot(Node).ToString());
        }
Ejemplo n.º 6
0
        public void TestAdd0()
        {
            var Node = (AstNode)((ast.Argument <int>(0, "Arg") + ast.Immediate(0)) * ast.Immediate(3));

            Assert.AreEqual("((Arg + 0) * 3)", new GeneratorCSharp().GenerateRoot(Node).ToString());
            Node = new AstOptimizer().Optimize(Node);
            Assert.AreEqual("(Arg * 3)", new GeneratorCSharp().GenerateRoot(Node).ToString());
        }
Ejemplo n.º 7
0
        public void TestCastToImmediate()
        {
            var node = (AstNode)_ast.Cast <uint>(_ast.Immediate(7));

            Assert.Equal("((UInt32)7)", new GeneratorCSharp().GenerateRoot(node).ToString());
            node = new AstOptimizer().Optimize(node);
            Assert.Equal("7", new GeneratorCSharp().GenerateRoot(node).ToString());
        }
Ejemplo n.º 8
0
        public void TestCompactStmContainer2()
        {
            var Node = (AstNode)ast.Statements(
                ast.Return()
                );

            Node = new AstOptimizer().Optimize(Node);
            Assert.AreEqual(
                "<AstNodeStmReturn />",
                AstSerializer.SerializeAsXml(Node, false)
                );
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Convert the given method into optimized Ast format.
        /// </summary>
        protected static AstNode CreateOptimizedAst(AssemblyCompiler compiler, MethodSource source)
        {
            // Build AST
            DecompilerContext context;
            AstBlock          ast;

            if (source.IsDotNet)
            {
                context = new DecompilerContext(source.Method);
                var astBuilder = new IL2Ast.AstBuilder(source.ILMethod, true, context);
                var children   = astBuilder.Build();
                ast = new AstBlock(children.Select(x => x.SourceLocation).FirstOrDefault(), children);
                if ((source.ILMethod.IsConstructor) && (source.Method.DeclaringType.Fields.Any(x => x.FieldType.IsEnum())))
                {
                    // Ensure all fields are initialized
                    AddFieldInitializationCode(source, ast);
                }
                if (source.Method.NeedsGenericInstanceTypeParameter && (source.Name == ".ctor"))
                {
                    // Add code to safe the generic instance type parameter into the generic instance field.
                    AddGenericInstanceFieldInitializationCode(ast);
                }
            }
            else if (source.IsJava)
            {
                var astBuilder = new Java2Ast.AstBuilder(compiler.Module, source.JavaMethod, source.Method.DeclaringType, true);
                context = new DecompilerContext(source.Method);
                ast     = astBuilder.Build();
            }
            else if (source.IsAst)
            {
                context = new DecompilerContext(source.Method);
                ast     = source.Ast;
            }
            else
            {
                throw new NotSupportedException("Unknown source");
            }

            // Optimize AST
            var astOptimizer = new AstOptimizer(context, ast);

            astOptimizer.Optimize();

            // Optimize AST towards the target
            TargetConverters.Convert(context, ast, source, compiler);

            // Return return
            return(ast);
        }
Ejemplo n.º 10
0
        public void TestCompactStmContainer()
        {
            var Node = (AstNode)ast.Statements(
                ast.Return(),
                ast.Statements(
                    ast.Statements(
                        ast.Return()
                        ),
                    ast.Return(),
                    ast.Statements(ast.Statements(ast.Statements())),
                    ast.Return(),
                    ast.Statements(
                        ast.Return()
                        )
                    ),
                ast.Return()
                );

            Node = new AstOptimizer().Optimize(Node);
            Assert.AreEqual(
                "AstNodeStmContainer(AstNodeStmReturn(), AstNodeStmReturn(), AstNodeStmReturn(), AstNodeStmReturn(), AstNodeStmReturn(), AstNodeStmReturn())",
                AstSerializer.Serialize(Node)
                );
        }
Ejemplo n.º 11
0
        public void TestCompactStmContainer()
        {
            var node = (AstNode)_ast.Statements(
                _ast.Return(),
                _ast.Statements(
                    _ast.Statements(
                        _ast.Return()
                        ),
                    _ast.Return(),
                    _ast.Statements(_ast.Statements(_ast.Statements())),
                    _ast.Return(),
                    _ast.Statements(
                        _ast.Return()
                        )
                    ),
                _ast.Return()
                );

            node = new AstOptimizer().Optimize(node);
            Assert.Equal(
                "AstNodeStmContainer(AstNodeStmReturn(), AstNodeStmReturn(), AstNodeStmReturn(), AstNodeStmReturn(), AstNodeStmReturn(), AstNodeStmReturn())",
                AstSerializer.Serialize(node)
                );
        }
        /// <summary>
        /// Load the text to display
        /// </summary>
        protected override string LoadText(ISpyContext settings)
        {
            var nl = Environment.NewLine;
            var sb = new StringBuilder();

            sb.AppendFormat("AccessFlags: {0} (0x{1:X4}){2}", AccessFlagsAsString(methodDef.AccessFlags), (int)methodDef.AccessFlags, nl);
            sb.AppendFormat("Descriptor:  {0}{1}", methodDef.Descriptor, nl);
            sb.AppendFormat("Signature:   {0}{1}", (methodDef.Signature != null) ? methodDef.Signature.Original : "<none>", nl);
            sb.AppendFormat("Annotations: {0}{1}", TextNode.LoadAnnotations(methodDef), nl);

            var code = methodDef.Attributes.OfType <CodeAttribute>().FirstOrDefault();

            if (code != null)
            {
                sb.AppendFormat("Max locals:  {0}{1}", code.MaxLocals, nl);
                sb.AppendFormat("Max stack:   {0}{1}", code.MaxStack, nl);
                sb.AppendLine("Code:");
                foreach (var i in code.Instructions)
                {
                    sb.AppendFormat("\t{0:x4} {1} {2} {3} {4}", i.Offset, Format(i.Opcode), FormatOperand(i.Operand), FormatOperand(i.Operand2), nl);
                }
                sb.AppendLine();

                if (code.ExceptionHandlers.Any())
                {
                    sb.AppendLine("Exception handlers:");
                    foreach (var handler in code.ExceptionHandlers.OrderBy(x => x.StartPc))
                    {
                        sb.AppendFormat("\t{0:x4}-{1:x4}  => {2:x4} ({3})  {4}", handler.StartPc, handler.EndPc, handler.HandlerPc, handler.CatchType, nl);
                    }
                    sb.AppendLine();
                }

                if (code.Attributes.OfType <LocalVariableTableAttribute>().Any())
                {
                    var locVarAttr = code.Attributes.OfType <LocalVariableTableAttribute>().First();
                    sb.AppendLine("Local variables:");
                    foreach (var locVar in locVarAttr.Variables.OrderBy(x => x.StartPc))
                    {
                        sb.AppendFormat("\t{0:x4}-{1:x4}  => {2} ({3})  {4}", locVar.StartPc, locVar.EndPc, locVar.Name, locVar.Index, nl);
                    }
                    sb.AppendLine();
                }

#if DEBUG || ENABLE_SHOW_AST
                if (settings.ShowAst)
                {
                    sb.AppendLine("\n\nAST:\n");
                    try
                    {
                        var module     = settings.Module;
                        var xMethod    = CompilerLib.XModel.Java.XBuilder.AsMethodDefinition(module, methodDef);
                        var astBuilder = new CompilerLib.Java2Ast.AstBuilder(module, methodDef, xMethod.DeclaringType, true);
                        var context    = new DecompilerContext(xMethod);
                        var ast        = astBuilder.Build();

                        var writer = new PlainTextOutput(new StringWriter(sb));
                        ast.WriteTo(writer, FormattingOptions.Default);
                        writer.WriteLine();

                        // Optimize AST
                        sb.AppendLine("\n\nOptimized AST:\n");
                        var astOptimizer = new AstOptimizer(context, ast);
                        astOptimizer.Optimize();
                        ast.WriteTo(writer, FormattingOptions.Default);
                        writer.WriteLine();
                    }
                    catch (Exception ex)
                    {
                        sb.Append(string.Format("Error: {0}\n\n{1}", ex.Message, ex.StackTrace));
                    }
                }
#endif
            }

            return(sb.ToString());
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Convert the given method into optimized Ast format.
        /// </summary>
        internal protected static AstNode CreateOptimizedAst(AssemblyCompiler compiler, MethodSource source,
                                                             bool generateSetNextInstructionCode,
                                                             StopAstConversion debugStop             = StopAstConversion.None,
                                                             AstOptimizationStep debugStopOptimizing = AstOptimizationStep.None
                                                             )
        {
            // Build AST
            DecompilerContext context;
            AstBlock          ast;

            if (source.IsDotNet)
            {
                context = new DecompilerContext(source.Method);
                var astBuilder = new IL2Ast.AstBuilder(source.ILMethod, true, context);
                var children   = astBuilder.Build();
                ast = new AstBlock(children.Select(x => x.SourceLocation).FirstOrDefault(), children);
                if ((source.ILMethod.IsConstructor) && (source.Method.DeclaringType.Fields.Any(x => x.FieldType.IsEnum() || x.Name.EndsWith(NameConstants.Atomic.FieldUpdaterPostfix))))
                {
                    // Ensure all fields are initialized
                    AddFieldInitializationCode(compiler, source, ast);
                }
                if (source.Method.NeedsGenericInstanceTypeParameter && (source.Name == ".ctor"))
                {
                    // Add code to save the generic instance type parameter into the generic instance field.
                    AddGenericInstanceFieldInitializationCode(source, ast, compiler.Module.TypeSystem);
                }
            }
            else if (source.IsJava)
            {
                var astBuilder = new Java2Ast.AstBuilder(compiler.Module, source.JavaMethod, source.Method.DeclaringType, true);
                context = new DecompilerContext(source.Method);
                ast     = astBuilder.Build();
            }
            else if (source.IsAst)
            {
                context = new DecompilerContext(source.Method);
                ast     = source.Ast;
            }
            else
            {
                throw new NotSupportedException("Unknown source");
            }

            if (debugStop == StopAstConversion.AfterILConversion)
            {
                return(ast);
            }

            // Optimize AST
            var astOptimizer = new AstOptimizer(context, ast);

            astOptimizer.Optimize(debugStopOptimizing);

            if (debugStop == StopAstConversion.AfterOptimizing)
            {
                return(ast);
            }

            // Optimize AST towards the target
            TargetConverters.Convert(context, ast, source, compiler, debugStop);

            if (generateSetNextInstructionCode)
            {
                SetNextInstructionGenerator.Convert(ast, source, compiler);
            }

            // Return return
            return(ast);
        }