Example #1
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;
        }
Example #2
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;
        }
        /// <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
                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);
                        writer.WriteLine();

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

            return sb.ToString();
        }