/// <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); }
/// <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); }