Exemplo n.º 1
0
        static BlockStatement ReplaceJump(JumpStatement jump, BlockStatement block)
        {
            if (jump.StartOffset < block.StartOffset)
                throw new ArgumentOutOfRangeException("jump", "jump should be inside the given block");
            if (jump.JumpOffset > block.EndOffset)
                throw new ArgumentOutOfRangeException("jump", "jump should be inside the given block");

            var newBlock = new BlockStatement();
            var ifStatement = new IfStatement(Not(jump.Condition), new BlockStatement()){ StartOffset = jump.StartOffset, EndOffset = jump.JumpOffset };
            var inside = false;
            foreach (var statement in block)
            {
                if (statement is IfStatement && statement.Contains(jump.StartOffset.Value) && statement.EndOffset >= jump.JumpOffset)
                {
                    var ifStatement2 = (IfStatement)statement;
                    var b2 = ReplaceJump(jump, (BlockStatement)ifStatement2.TrueStatement);
                    var newIfStatement2 = new IfStatement(ifStatement2.Condition, new BlockStatement()){ StartOffset = ifStatement2.StartOffset, EndOffset = ifStatement2.EndOffset };
                    ((BlockStatement)newIfStatement2.TrueStatement).AddStatements((IEnumerable<Statement>)b2);
                    newBlock.AddStatement(newIfStatement2);
                }
                else if (statement.StartOffset == jump.StartOffset)
                {                    
                    inside = true;
                }
                else if (statement.StartOffset == jump.JumpOffset)
                {
                    if (ifStatement == null)
                        throw new InvalidOperationException("ifStatement can't be null");
                    newBlock.AddStatement(ifStatement);
                    newBlock.AddStatement(statement);
                    ifStatement = null;
                    inside = false;
                }
                else if (inside)
                {
                    ((BlockStatement)ifStatement.TrueStatement).AddStatement(statement);
                }
                else
                {
                    var lastStatement = newBlock.LastOrDefault();
                    if (lastStatement != null && lastStatement.EndOffset > statement.StartOffset)
                    {
                        throw new NotSupportedException("invalid Statement");
                    }
                    newBlock.AddStatement(statement);
                }
            }
            return newBlock;
        }
Exemplo n.º 2
0
        private CachedDecompiledMember DecompileMethod(ILanguage language, MethodDefinition method, TypeSpecificContext typeContext)
        {
            CachedDecompiledMember decompiledMember;
            Statement statement;

            try
            {
                DecompilationContext innerContext = null;
                statement        = method.Body.Decompile(language, out innerContext, typeContext);
                decompiledMember = new CachedDecompiledMember(new DecompiledMember(Utilities.GetMemberUniqueName(method), statement, innerContext.MethodContext), innerContext.TypeContext);
            }
            catch (Exception ex)
            {
                this.ExceptionsWhileDecompiling.Add(method);

                BlockStatement blockStatement = new BlockStatement();
                statement = new ExceptionStatement(ex, method);
                blockStatement.AddStatement(statement);

                decompiledMember = new CachedDecompiledMember(new DecompiledMember(Utilities.GetMemberUniqueName(method), blockStatement, new MethodSpecificContext(method.Body)));

                OnExceptionThrown(ex);
            }
            return(decompiledMember);
        }
Exemplo n.º 3
0
        private BlockStatement DecompileMethod(MethodBody body, out MethodSpecificContext methodContext)
        {
            methodContext = null;

            BlockStatement block;

            try
            {
                DecompilationContext decompilationContext =
                    new DecompilationContext(new MethodSpecificContext(body), this.typeContext ?? new TypeSpecificContext(body.Method.DeclaringType));

                DecompilationPipeline pipeline = this.language.CreatePipeline(body.Method, decompilationContext);

                methodContext = pipeline.Run(body).MethodContext;

                block = pipeline.Body;
            }
            catch (Exception ex)
            {
                this.ExceptionsWhileDecompiling.Add(body.Method);

                methodContext = new MethodSpecificContext(body);

                block = new BlockStatement();
                block.AddStatement(new ExceptionStatement(ex, body.Method));

                OnExceptionThrown(ex);
            }

            return(block);
        }
Exemplo n.º 4
0
        private BlockStatement FinishDecompilationOfMethod(BlockStatement block, DecompilationContext context, out MethodSpecificContext methodContext)
        {
            methodContext = null;

            BlockStatement fullyDecompiledBlock;

            try
            {
                BlockDecompilationPipeline pipeline = this.language.CreatePropertyPipeline(context.MethodContext.Method, context);

                methodContext = pipeline.Run(context.MethodContext.Method.Body, block, this.language).MethodContext;

                fullyDecompiledBlock = pipeline.Body;
            }
            catch (Exception ex)
            {
                this.ExceptionsWhileDecompiling.Add(context.MethodContext.Method);

                methodContext = new MethodSpecificContext(context.MethodContext.Method.Body);

                fullyDecompiledBlock = new BlockStatement();
                fullyDecompiledBlock.AddStatement(new ExceptionStatement(ex, context.MethodContext.Method));

                OnExceptionThrown(ex);
            }

            return(fullyDecompiledBlock);
        }
        private IStatement IfNull(Type returnType)
        {
            var statements = new BlockStatement();

            InitOutParameters(statements, MethodToOverride.GetParameters());

            if (returnType == typeof(void))
            {
                statements.AddStatement(new ReturnStatement());
            }
            else
            {
                statements.AddStatement(new ReturnStatement(new DefaultValueExpression(returnType)));
            }
            return(statements);
        }
Exemplo n.º 6
0
        private ICodeNode ConvertLambda(MethodInvocationExpression invocation)
        {
            if (invocation.Arguments.Count != 2)
            {
                return(null);
            }

            ArrayCreationExpression arguments = Visit(invocation.Arguments[1]) as ArrayCreationExpression;

            if (arguments == null || arguments.Initializer == null || arguments.Initializer.Expressions == null ||
                arguments.Initializer.Expressions.Any(element => element.CodeNodeType != CodeNodeType.ArgumentReferenceExpression))
            {
                return(null);
            }

            List <ArgumentReferenceExpression> parameters = arguments.Initializer.Expressions.Cast <ArgumentReferenceExpression>().ToList();

            bool hasAnonymousParameter = parameters.Any(param => param.Parameter.ParameterType.Resolve().IsAnonymous());

            BlockStatement body = new BlockStatement();

            body.AddStatement(new ExpressionStatement(new ShortFormReturnExpression((Expression)Visit(invocation.Arguments[0]), null)));

            return(new LambdaExpression(new ExpressionCollection(parameters.Select(param => new LambdaParameterExpression(param.Parameter, !hasAnonymousParameter, null))),
                                        body, false, false, parameters.Select(argRef => argRef.Parameter), true, null));
        }
Exemplo n.º 7
0
 private BlockStatement DecompileMethod(MethodBody body, out MethodSpecificContext methodContext)
 {
     methodContext = null;
     try
     {
         stackVariable3 = new MethodSpecificContext(body);
         stackVariable5 = this.typeContext;
         if (stackVariable5 == null)
         {
             dummyVar0      = stackVariable5;
             stackVariable5 = new TypeSpecificContext(body.get_Method().get_DeclaringType());
         }
         V_1           = new DecompilationContext(stackVariable3, stackVariable5, this.language);
         V_2           = this.language.CreatePipeline(V_1);
         methodContext = V_2.Run(body, this.language).get_MethodContext();
         V_0           = V_2.get_Body();
     }
     catch (Exception exception_0)
     {
         V_3 = exception_0;
         this.get_ExceptionsWhileDecompiling().Add(body.get_Method());
         methodContext = new MethodSpecificContext(body);
         V_0           = new BlockStatement();
         V_0.AddStatement(new ExceptionStatement(V_3, body.get_Method()));
         this.OnExceptionThrown(V_3);
     }
     return(V_0);
 }
Exemplo n.º 8
0
 private void MoveInCase(IfStatement gotoStatement, SwitchCase switchCase, string label)
 {
     V_0             = new VariableReferenceExpression(this.GetLabelVariable(label), null);
     V_1             = this.GetOuterBlock(gotoStatement);
     V_2             = switchCase.get_Parent() as SwitchStatement;
     V_3             = V_1.get_Statements().IndexOf(gotoStatement);
     V_4             = V_1.get_Statements().IndexOf(V_2);
     V_12            = V_2.get_ConditionBlock().get_First().get_Offset();
     stackVariable26 = String.Concat("switch", V_12.ToString());
     V_5             = this.GetSwitchType(V_2);
     V_6             = new VariableDefinition(stackVariable26, V_5, this.methodContext.get_Method());
     this.switchVariables.Add(V_6);
     V_7 = new VariableReferenceExpression(V_6, null);
     this.ExtractConditionIntoVariable(V_7, V_2, V_1);
     V_8  = this.CollectStatements(V_3 + 1, V_4 + 1, V_1);
     V_9  = new BlockStatement();
     V_10 = new BinaryExpression(26, V_7.CloneExpressionOnly(), this.GetCaseConditionExpression(switchCase), this.typeSystem, null, false);
     V_9.AddStatement(new ExpressionStatement(V_10));
     V_11 = new IfStatement(new UnaryExpression(1, V_0, null), V_8, V_9);
     if (V_11.get_Then().get_Statements().get_Count() != 0)
     {
         V_1.AddStatementAt(V_3, V_11);
     }
     dummyVar0 = V_1.get_Statements().Remove(gotoStatement);
     switchCase.get_Body().AddStatementAt(0, gotoStatement);
     return;
 }
Exemplo n.º 9
0
 private void AddBreakContinueConditional(int index, BlockStatement containingBlock, Statement statement, VariableReference conditionVariable)
 {
     V_0 = new BlockStatement();
     V_0.AddStatement(statement);
     V_1 = new IfStatement(new VariableReferenceExpression(conditionVariable, null), V_0, null);
     containingBlock.AddStatementAt(index, V_1);
     return;
 }
Exemplo n.º 10
0
 private void CopyWhileBodyStatements(WhileStatement whileStatement)
 {
     statementBody = new BlockStatement();
     for (int i = 1; i < whileStatement.Body.Statements.Count - 1; i++)
     {
         statementBody.AddStatement(whileStatement.Body.Statements[i]);
     }
 }
Exemplo n.º 11
0
        //Methods public
        private IStatement Parse()
        {
            BlockStatement program = new BlockStatement();

            while (position < tokens.Count)
            {
                program.AddStatement(GetStatement());
            }
            return(program);
        }
Exemplo n.º 12
0
        INode InitStaticVariable(string initFieldName, string variableName, Expression initializer, TypeDeclaration typeDeclaration)
        {
            const string helperMethodName = "InitStaticVariableHelper";

            if (typeDeclaration != null)
            {
                if (!typeDeclaration.Children.OfType <MethodDeclaration>().Any(m => m.Name == helperMethodName))
                {
                    // add helper method
                    var helperMethod = new MethodDeclaration {
                        Name          = helperMethodName,
                        Modifier      = Modifiers.Static,
                        TypeReference = new TypeReference("System.Boolean", true),
                        Parameters    =
                        {
                            new ParameterDeclarationExpression(new TypeReference("Microsoft.VisualBasic.CompilerServices.StaticLocalInitFlag"), "flag")
                        },
                        Body = new BlockStatement()
                    };
                    BlockStatement trueBlock   = new BlockStatement();
                    BlockStatement elseIfBlock = new BlockStatement();
                    BlockStatement falseBlock  = new BlockStatement();
                    helperMethod.Body.AddStatement(
                        new IfElseStatement(ExpressionBuilder.Identifier("flag").Member("State").Operator(BinaryOperatorType.Equality, new PrimitiveExpression(0)))
                    {
                        TrueStatement  = { trueBlock },
                        ElseIfSections =
                        {
                            new ElseIfSection(ExpressionBuilder.Identifier("flag").Member("State").Operator(BinaryOperatorType.Equality, new PrimitiveExpression(2)), elseIfBlock)
                        },
                        FalseStatement = { falseBlock }
                    });
                    trueBlock.Assign(ExpressionBuilder.Identifier("flag").Member("State"), new PrimitiveExpression(2));
                    trueBlock.Return(new PrimitiveExpression(true));
                    elseIfBlock.Throw(new TypeReference("Microsoft.VisualBasic.CompilerServices.IncompleteInitialization").New());
                    falseBlock.Return(new PrimitiveExpression(false));
                    typeDeclaration.AddChild(helperMethod);
                }
            }

            BlockStatement tryBlock    = new BlockStatement();
            BlockStatement ifTrueBlock = new BlockStatement();

            tryBlock.AddStatement(new IfElseStatement(ExpressionBuilder.Identifier(helperMethodName).Call(ExpressionBuilder.Identifier(initFieldName)), ifTrueBlock));
            ifTrueBlock.Assign(ExpressionBuilder.Identifier(variableName), initializer);

            BlockStatement finallyBlock = new BlockStatement();

            finallyBlock.Assign(ExpressionBuilder.Identifier(initFieldName).Member("State"), new PrimitiveExpression(1));

            BlockStatement lockBlock = new BlockStatement();

            lockBlock.AddStatement(new TryCatchStatement(tryBlock, null, finallyBlock));
            return(new LockStatement(ExpressionBuilder.Identifier(initFieldName), lockBlock));
        }
Exemplo n.º 13
0
 public BlockStatement Process(DecompilationContext context, BlockStatement body)
 {
     V_0 = context.get_MethodContext().get_Method();
     if (!V_0.get_IsUnsafe() && V_0.get_HasBody() && this.IsUnsafe(V_0.get_Body().get_Instructions()))
     {
         V_1 = new UnsafeBlockStatement(body.get_Statements());
         body.set_Statements(new StatementCollection());
         body.AddStatement(V_1);
     }
     return(body);
 }
Exemplo n.º 14
0
        static BlockStatement ReplaceJump(JumpStatement jump, BlockStatement block)
        {
            if (jump.StartOffset < block.StartOffset)
                throw new ArgumentOutOfRangeException("jump", "jump should be inside the given block");
            if (jump.JumpOffset > block.EndOffset)
                throw new ArgumentOutOfRangeException("jump", "jump should be inside the given block");

            var newBlock = new BlockStatement();
            var doWhileStatement = new DoWhileStatement(jump.Condition, new BlockStatement()){ StartOffset = jump.StartOffset, EndOffset = jump.JumpOffset };
            var inside = false;
            foreach (var statement in block)
            {
                if (statement.StartOffset == jump.JumpOffset)
                {                    
                    ((BlockStatement)doWhileStatement.Statement).AddStatement(statement);
                    inside = true;
                }
                else if (statement.StartOffset == jump.StartOffset)
                {
                    if (doWhileStatement == null)
                        throw new InvalidOperationException("DoWhileStatement can't be null");
                    newBlock.AddStatement(doWhileStatement);
                    doWhileStatement = null;
                    inside = false;
                }
                else if (inside)
                {
                    ((BlockStatement)doWhileStatement.Statement).AddStatement(statement);
                }
                else
                {
                    var lastStatement = newBlock.LastOrDefault();
                    if (lastStatement != null && lastStatement.EndOffset > statement.StartOffset)
                    {
                        throw new NotSupportedException("invalid Statement");
                    }
                    newBlock.AddStatement(statement);
                }
            }
            return newBlock;
        }
Exemplo n.º 15
0
 private BlockStatement CollectStatements(int startingIndex, int endingIndex, BlockStatement containingBlock)
 {
     V_0 = new BlockStatement();
     V_1 = startingIndex;
     while (V_1 < endingIndex)
     {
         V_0.AddStatement(containingBlock.get_Statements().get_Item(V_1));
         containingBlock.get_Statements().RemoveAt(V_1);
         endingIndex = endingIndex - 1;
     }
     return(V_0);
 }
 private void InitOutParameters(BlockStatement statements, ParameterInfo[] parameters)
 {
     for (var index = 0; index < parameters.Length; index++)
     {
         var parameter = parameters[index];
         if (parameter.IsOut)
         {
             statements.AddStatement(
                 new AssignArgumentStatement(new ArgumentReference(parameter.ParameterType, index + 1),
                                             new DefaultValueExpression(parameter.ParameterType)));
         }
     }
 }
        public BlockStatement Process(DecompilationContext context, BlockStatement body)
        {
            MethodDefinition method = context.MethodContext.Method;

            if (!method.IsUnsafe && method.HasBody && IsUnsafe(method.Body.Instructions))
            {
                UnsafeBlockStatement unsafeStatement = new UnsafeBlockStatement(body.Statements);
                body.Statements = new StatementCollection();
                body.AddStatement(unsafeStatement);
            }

            return(body);
        }
Exemplo n.º 18
0
        private IStatement CreateBlock()
        {
            BlockStatement block = new BlockStatement();

            if (!MatchToken(TokenType.LBlock))
            {
                throw new Exception("Block has no LBlock. CreateBlock");
            }
            while (!MatchToken(TokenType.RBlock))
            {
                block.AddStatement(GetStatement());
            }
            return(block);
        }
        private IStatement IfNotNull(Reference targetReference)
        {
            var statements = new BlockStatement();
            var arguments  = ArgumentsUtil.ConvertToArgumentReferenceExpression(MethodToOverride.GetParameters());

            statements.AddStatement(new ReturnStatement(
                                        new MethodInvocationExpression(
                                            targetReference,
                                            MethodToOverride,
                                            arguments)
            {
                VirtualCall = true
            }));
            return(statements);
        }
Exemplo n.º 20
0
        private BlockStatement DecompileMethodPartially(MethodBody body, out DecompilationContext context, bool needDecompiledMember = false)
        {
            context = null;

            if (this.IsCachingEnabled && this.cacheService.IsDecompiledMemberInCache(body.Method, this.language, this.renameInvalidMembers))
            {
                CachedDecompiledMember cachedDecompiledMember = this.cacheService.GetDecompiledMemberFromCache(body.Method, this.language, this.renameInvalidMembers);
                return(cachedDecompiledMember.Member.Statement as BlockStatement);
            }

            //Performance improvement
            ControlFlowGraph cfg = new ControlFlowGraphBuilder(body.Method).CreateGraph();

            if (cfg.Blocks.Length > 2)
            {
                return(null);
            }

            BlockStatement block;

            try
            {
                DecompilationPipeline pipeline;
                DecompilationContext  decompilationContext =
                    new DecompilationContext(new MethodSpecificContext(body), this.typeContext ?? new TypeSpecificContext(body.Method.DeclaringType));
                if (!needDecompiledMember)
                {
                    decompilationContext.MethodContext.EnableEventAnalysis = false;
                }

                pipeline = new DecompilationPipeline(BaseLanguage.IntermediateRepresenationPipeline.Steps, decompilationContext);

                context = pipeline.Run(body);

                block = pipeline.Body;
            }
            catch (Exception ex)
            {
                this.ExceptionsWhileDecompiling.Add(body.Method);

                block = new BlockStatement();
                block.AddStatement(new ExceptionStatement(ex, body.Method));

                OnExceptionThrown(ex);
            }

            return(block);
        }
Exemplo n.º 21
0
 private void EmbedIntoDefaultIf(GotoStatement jump)
 {
     V_0 = jump.get_Parent() as BlockStatement;
     V_1 = new BlockStatement();
     V_1.AddStatement(jump);
     V_2 = new IfStatement(this.GetLiteralExpression(true), V_1, null);
     V_1.set_Parent(V_2);
     V_3 = V_0.get_Statements().IndexOf(jump);
     V_0.get_Statements().RemoveAt(V_3);
     V_0.AddStatementAt(V_3, V_2);
     if (V_0.get_Parent() as ConditionCase != null && V_0.get_Statements().IndexOf(V_2) == V_0.get_Statements().get_Count())
     {
         V_0.AddStatement(new BreakStatement(null));
     }
     return;
 }
Exemplo n.º 22
0
 private CachedDecompiledMember DecompileMethod(ILanguage language, MethodDefinition method, TypeSpecificContext typeContext)
 {
     try
     {
         V_2 = null;
         V_1 = method.get_Body().Decompile(language, out V_2, typeContext);
         V_0 = new CachedDecompiledMember(new DecompiledMember(Utilities.GetMemberUniqueName(method), V_1, V_2.get_MethodContext()), V_2.get_TypeContext());
     }
     catch (Exception exception_0)
     {
         V_3 = exception_0;
         this.get_ExceptionsWhileDecompiling().Add(method);
         V_4 = new BlockStatement();
         V_4.AddStatement(new ExceptionStatement(V_3, method));
         V_0 = new CachedDecompiledMember(new DecompiledMember(Utilities.GetMemberUniqueName(method), V_4, new MethodSpecificContext(method.get_Body())));
         this.OnExceptionThrown(V_3);
     }
     return(V_0);
 }
Exemplo n.º 23
0
 private void MoveOut(IfStatement gotoStatement, string label)
 {
     V_0 = gotoStatement.get_Parent() as BlockStatement;
     V_1 = this.GetOuterBlock(V_0);
     V_2 = new VariableReferenceExpression(this.GetLabelVariable(label), null);
     this.ExtractConditionIntoVariable(V_2.CloneExpressionOnly() as VariableReferenceExpression, gotoStatement, V_0);
     V_3 = V_0.get_Parent();
     if (V_3 as SwitchCase != null)
     {
         V_3 = V_3.get_Parent();
     }
     if (V_0.get_Parent() as SwitchCase != null || V_0.get_Parent() as WhileStatement != null || V_0.get_Parent() as DoWhileStatement != null || V_0.get_Parent() as ForStatement != null || V_0.get_Parent() as ForEachStatement != null)
     {
         V_4 = new BlockStatement();
         V_4.AddStatement(new BreakStatement(null));
         V_5       = new IfStatement(V_2.CloneExpressionOnly(), V_4, null);
         V_6       = V_0.get_Statements().IndexOf(gotoStatement);
         dummyVar0 = V_0.get_Statements().Remove(gotoStatement);
         V_0.AddStatementAt(V_6, V_5);
     }
     else
     {
         if (V_0.get_Parent() as IfStatement == null && V_0.get_Parent() as TryStatement == null && V_0.get_Parent() as IfElseIfStatement == null)
         {
             throw new ArgumentOutOfRangeException("Goto statement can not leave this parent construct.");
         }
         V_7 = V_0.get_Statements().IndexOf(gotoStatement) + 1;
         V_8 = new BlockStatement();
         while (V_7 < V_0.get_Statements().get_Count())
         {
             V_8.AddStatement(V_0.get_Statements().get_Item(V_7));
             V_0.get_Statements().RemoveAt(V_7);
         }
         V_9       = new IfStatement(new UnaryExpression(1, V_2.CloneExpressionOnly(), null), V_8, null);
         dummyVar1 = V_0.get_Statements().Remove(gotoStatement);
         if (V_9.get_Then().get_Statements().get_Count() != 0)
         {
             V_0.AddStatement(V_9);
         }
     }
     V_1.AddStatementAt(V_1.get_Statements().IndexOf(V_3) + 1, gotoStatement);
     return;
 }
        private Statement ProcessBlockStatement(BlockStatementNode node)
        {
            BlockStatement statement = new BlockStatement();

            _symbolTable.PushScope();

            foreach (StatementNode childStatementNode in node.Statements)
            {
                Statement childStatement = BuildStatement(childStatementNode);
                if (childStatement != null)
                {
                    statement.AddStatement(childStatement);
                }
            }

            _symbolTable.PopScope();

            return(statement);
        }
Exemplo n.º 25
0
 private BlockStatement FinishDecompilationOfMethod(BlockStatement block, DecompilationContext context, out MethodSpecificContext methodContext)
 {
     methodContext = null;
     try
     {
         V_1           = this.language.CreatePropertyPipeline(context);
         methodContext = V_1.Run(context.get_MethodContext().get_Method().get_Body(), block, this.language).get_MethodContext();
         V_0           = V_1.get_Body();
     }
     catch (Exception exception_0)
     {
         V_2 = exception_0;
         this.get_ExceptionsWhileDecompiling().Add(context.get_MethodContext().get_Method());
         methodContext = new MethodSpecificContext(context.get_MethodContext().get_Method().get_Body());
         V_0           = new BlockStatement();
         V_0.AddStatement(new ExceptionStatement(V_2, context.get_MethodContext().get_Method()));
         this.OnExceptionThrown(V_2);
     }
     return(V_0);
 }
Exemplo n.º 26
0
 private BlockStatement DecompileMethodPartially(MethodBody body, out DecompilationContext context, bool needDecompiledMember = false)
 {
     context = null;
     if (this.get_IsCachingEnabled() && this.cacheService.IsDecompiledMemberInCache(body.get_Method(), this.language, this.renameInvalidMembers))
     {
         return(this.cacheService.GetDecompiledMemberFromCache(body.get_Method(), this.language, this.renameInvalidMembers).get_Member().get_Statement() as BlockStatement);
     }
     if ((int)(new ControlFlowGraphBuilder(body.get_Method())).CreateGraph().get_Blocks().Length > 2)
     {
         return(null);
     }
     try
     {
         stackVariable13 = new MethodSpecificContext(body);
         stackVariable15 = this.typeContext;
         if (stackVariable15 == null)
         {
             dummyVar0       = stackVariable15;
             stackVariable15 = new TypeSpecificContext(body.get_Method().get_DeclaringType());
         }
         V_2 = new DecompilationContext(stackVariable13, stackVariable15, this.language);
         if (!needDecompiledMember)
         {
             V_2.get_MethodContext().set_EnableEventAnalysis(false);
         }
         V_1     = new DecompilationPipeline(BaseLanguage.get_IntermediateRepresenationPipeline().get_Steps(), V_2);
         context = V_1.Run(body, this.language);
         V_0     = V_1.get_Body();
     }
     catch (Exception exception_0)
     {
         V_3 = exception_0;
         this.get_ExceptionsWhileDecompiling().Add(body.get_Method());
         V_0 = new BlockStatement();
         V_0.AddStatement(new ExceptionStatement(V_3, body.get_Method()));
         this.OnExceptionThrown(V_3);
     }
     return(V_0);
 }
Exemplo n.º 27
0
        /// <summary>
        /// Parser for BlockStatement
        /// </summary>
        /// <returns>Parsed BlockStatement</returns>
        public BlockStatement ParseBlockStatement()
        {
            BlockStatement blockStatement = new BlockStatement();

            //Skip { token
            NextToken("{", "{ statements* }", '{');

            //Parse statements
            while (TokenStream.HasNext())
            {
                if (TokenStream.Peek(1).GetValue().ToString() == "}")
                {   //End of blockstatement
                    break;
                }

                blockStatement.AddStatement(ParseStatement());
            }

            //Skip } token
            NextToken("}", "{ statements* }", '}');

            return blockStatement;
        }
Exemplo n.º 28
0
        AstNode TransformByteCode_Internal(MethodDefinition methodDef, ILExpression byteCode, List<Ast.Expression> args)
        {
            // throw new NotImplementedException();

            OpCode opCode = byteCode.OpCode;
            object operand = byteCode.Operand;
            AstType operandAsTypeRef = AstBuilder.ConvertType(operand as Cecil.TypeReference);
            ILExpression operandAsByteCode = operand as ILExpression;
            Ast.Expression arg1 = args.Count >= 1 ? args[0] : null;
            Ast.Expression arg2 = args.Count >= 2 ? args[1] : null;
            Ast.Expression arg3 = args.Count >= 3 ? args[2] : null;

            BlockStatement branchCommand = null;
            if (byteCode.Operand is ILLabel) {
                branchCommand = new BlockStatement();
                branchCommand.AddStatement(new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name));
            }

            switch(opCode.Code) {
                    #region Arithmetic
                    case Code.Add:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
                    case Code.Add_Ovf:    return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
                    case Code.Add_Ovf_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
                    case Code.Div:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Divide, arg2);
                    case Code.Div_Un:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Divide, arg2);
                    case Code.Mul:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2);
                    case Code.Mul_Ovf:    return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2);
                    case Code.Mul_Ovf_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2);
                    case Code.Rem:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Modulus, arg2);
                    case Code.Rem_Un:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Modulus, arg2);
                    case Code.Sub:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2);
                    case Code.Sub_Ovf:    return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2);
                    case Code.Sub_Ovf_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2);
                    case Code.And:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.BitwiseAnd, arg2);
                    case Code.Or:         return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.BitwiseOr, arg2);
                    case Code.Xor:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ExclusiveOr, arg2);
                    case Code.Shl:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftLeft, arg2);
                    case Code.Shr:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftRight, arg2);
                    case Code.Shr_Un:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftRight, arg2);

                    case Code.Neg:        return new Ast.UnaryOperatorExpression(UnaryOperatorType.Minus, arg1);
                    case Code.Not:        return new Ast.UnaryOperatorExpression(UnaryOperatorType.BitNot, arg1);
                    #endregion
                    #region Arrays
                case Code.Newarr:
                    operandAsTypeRef = operandAsTypeRef.MakeArrayType(0);
                    return new Ast.ArrayCreateExpression {
                        Type = operandAsTypeRef,
                        Arguments = new Expression[] {arg1}
                    };

                case Code.Ldlen:
                    return arg1.Member("Length");

                case Code.Ldelem_I:
                case Code.Ldelem_I1:
                case Code.Ldelem_I2:
                case Code.Ldelem_I4:
                case Code.Ldelem_I8:
                case Code.Ldelem_U1:
                case Code.Ldelem_U2:
                case Code.Ldelem_U4:
                case Code.Ldelem_R4:
                case Code.Ldelem_R8:
                case Code.Ldelem_Ref:
                    return arg1.Indexer(arg2);
                case Code.Ldelem_Any:
                    throw new NotImplementedException();
                case Code.Ldelema:
                    return MakeRef(arg1.Indexer(arg2));

                case Code.Stelem_I:
                case Code.Stelem_I1:
                case Code.Stelem_I2:
                case Code.Stelem_I4:
                case Code.Stelem_I8:
                case Code.Stelem_R4:
                case Code.Stelem_R8:
                case Code.Stelem_Ref:
                    return new Ast.AssignmentExpression(arg1.Indexer(arg2), arg3);
                case Code.Stelem_Any:
                    throw new NotImplementedException();
                    #endregion
                    #region Branching
                    case Code.Br:      return new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name);
                    case Code.Brfalse: return new Ast.IfElseStatement(new Ast.UnaryOperatorExpression(UnaryOperatorType.Not, arg1), branchCommand);
                    case Code.Brtrue:  return new Ast.IfElseStatement(arg1, branchCommand);
                    case Code.Beq:     return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Equality, arg2), branchCommand);
                    case Code.Bge:     return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThanOrEqual, arg2), branchCommand);
                    case Code.Bge_Un:  return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThanOrEqual, arg2), branchCommand);
                    case Code.Bgt:     return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2), branchCommand);
                    case Code.Bgt_Un:  return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2), branchCommand);
                    case Code.Ble:     return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThanOrEqual, arg2), branchCommand);
                    case Code.Ble_Un:  return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThanOrEqual, arg2), branchCommand);
                    case Code.Blt:     return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2), branchCommand);
                    case Code.Blt_Un:  return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2), branchCommand);
                    case Code.Bne_Un:  return new Ast.IfElseStatement(new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.InEquality, arg2), branchCommand);
                    #endregion
                    #region Comparison
                    case Code.Ceq:    return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Equality, ConvertIntToBool(arg2));
                    case Code.Cgt:    return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2);
                    case Code.Cgt_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2);
                    case Code.Clt:    return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2);
                    case Code.Clt_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2);
                    #endregion
                    #region Conversions
                    case Code.Conv_I:    return arg1.CastTo(typeof(int)); // TODO
                    case Code.Conv_I1:   return arg1.CastTo(typeof(SByte));
                    case Code.Conv_I2:   return arg1.CastTo(typeof(Int16));
                    case Code.Conv_I4:   return arg1.CastTo(typeof(Int32));
                    case Code.Conv_I8:   return arg1.CastTo(typeof(Int64));
                    case Code.Conv_U:    return arg1.CastTo(typeof(uint)); // TODO
                    case Code.Conv_U1:   return arg1.CastTo(typeof(Byte));
                    case Code.Conv_U2:   return arg1.CastTo(typeof(UInt16));
                    case Code.Conv_U4:   return arg1.CastTo(typeof(UInt32));
                    case Code.Conv_U8:   return arg1.CastTo(typeof(UInt64));
                    case Code.Conv_R4:   return arg1.CastTo(typeof(float));
                    case Code.Conv_R8:   return arg1.CastTo(typeof(double));
                    case Code.Conv_R_Un: return arg1.CastTo(typeof(double)); // TODO

                    case Code.Conv_Ovf_I:  return arg1.CastTo(typeof(int));
                    case Code.Conv_Ovf_I1: return arg1.CastTo(typeof(SByte));
                    case Code.Conv_Ovf_I2: return arg1.CastTo(typeof(Int16));
                    case Code.Conv_Ovf_I4: return arg1.CastTo(typeof(Int32));
                    case Code.Conv_Ovf_I8: return arg1.CastTo(typeof(Int64));
                    case Code.Conv_Ovf_U:  return arg1.CastTo(typeof(uint));
                    case Code.Conv_Ovf_U1: return arg1.CastTo(typeof(Byte));
                    case Code.Conv_Ovf_U2: return arg1.CastTo(typeof(UInt16));
                    case Code.Conv_Ovf_U4: return arg1.CastTo(typeof(UInt32));
                    case Code.Conv_Ovf_U8: return arg1.CastTo(typeof(UInt64));

                    case Code.Conv_Ovf_I_Un:  return arg1.CastTo(typeof(int));
                    case Code.Conv_Ovf_I1_Un: return arg1.CastTo(typeof(SByte));
                    case Code.Conv_Ovf_I2_Un: return arg1.CastTo(typeof(Int16));
                    case Code.Conv_Ovf_I4_Un: return arg1.CastTo(typeof(Int32));
                    case Code.Conv_Ovf_I8_Un: return arg1.CastTo(typeof(Int64));
                    case Code.Conv_Ovf_U_Un:  return arg1.CastTo(typeof(uint));
                    case Code.Conv_Ovf_U1_Un: return arg1.CastTo(typeof(Byte));
                    case Code.Conv_Ovf_U2_Un: return arg1.CastTo(typeof(UInt16));
                    case Code.Conv_Ovf_U4_Un: return arg1.CastTo(typeof(UInt32));
                    case Code.Conv_Ovf_U8_Un: return arg1.CastTo(typeof(UInt64));
                    #endregion
                    #region Indirect
                    case Code.Ldind_I: throw new NotImplementedException();
                    case Code.Ldind_I1: throw new NotImplementedException();
                    case Code.Ldind_I2: throw new NotImplementedException();
                    case Code.Ldind_I4: throw new NotImplementedException();
                    case Code.Ldind_I8: throw new NotImplementedException();
                    case Code.Ldind_U1: throw new NotImplementedException();
                    case Code.Ldind_U2: throw new NotImplementedException();
                    case Code.Ldind_U4: throw new NotImplementedException();
                    case Code.Ldind_R4: throw new NotImplementedException();
                    case Code.Ldind_R8: throw new NotImplementedException();
                    case Code.Ldind_Ref: throw new NotImplementedException();

                    case Code.Stind_I: throw new NotImplementedException();
                    case Code.Stind_I1: throw new NotImplementedException();
                    case Code.Stind_I2: throw new NotImplementedException();
                    case Code.Stind_I4: throw new NotImplementedException();
                    case Code.Stind_I8: throw new NotImplementedException();
                    case Code.Stind_R4: throw new NotImplementedException();
                    case Code.Stind_R8: throw new NotImplementedException();
                    case Code.Stind_Ref: throw new NotImplementedException();
                    #endregion
                    case Code.Arglist: throw new NotImplementedException();
                    case Code.Box: throw new NotImplementedException();
                    case Code.Break: throw new NotImplementedException();
                case Code.Call:
                    return TransformCall(false, operand, methodDef, args);
                case Code.Callvirt:
                    return TransformCall(true, operand, methodDef, args);
                case Code.Ldftn:
                    {
                        Cecil.MethodReference cecilMethod = ((MethodReference)operand);
                        var expr = new Ast.IdentifierExpression(cecilMethod.Name);
                        expr.TypeArguments = ConvertTypeArguments(cecilMethod);
                        expr.AddAnnotation(cecilMethod);
                        return new IdentifierExpression("ldftn").Invoke(expr)
                            .WithAnnotation(new Transforms.DelegateConstruction.Annotation(false, methodDef.DeclaringType));
                    }
                case Code.Ldvirtftn:
                    {
                        Cecil.MethodReference cecilMethod = ((MethodReference)operand);
                        var expr = new Ast.IdentifierExpression(cecilMethod.Name);
                        expr.TypeArguments = ConvertTypeArguments(cecilMethod);
                        expr.AddAnnotation(cecilMethod);
                        return new IdentifierExpression("ldvirtftn").Invoke(expr)
                            .WithAnnotation(new Transforms.DelegateConstruction.Annotation(true, methodDef.DeclaringType));
                    }

                    case Code.Calli: throw new NotImplementedException();
                    case Code.Castclass: return arg1.CastTo(operandAsTypeRef);
                    case Code.Ckfinite: throw new NotImplementedException();
                    case Code.Constrained: throw new NotImplementedException();
                    case Code.Cpblk: throw new NotImplementedException();
                    case Code.Cpobj: throw new NotImplementedException();
                    case Code.Dup: return arg1;
                    case Code.Endfilter: throw new NotImplementedException();
                    case Code.Endfinally: return null;
                    case Code.Initblk: throw new NotImplementedException();
                    case Code.Initobj: throw new NotImplementedException();
                    case Code.Isinst: return arg1.IsType(AstBuilder.ConvertType((Cecil.TypeReference)operand));
                    case Code.Jmp: throw new NotImplementedException();
                case Code.Ldarg:
                    if (methodDef.HasThis && ((ParameterDefinition)operand).Index < 0) {
                        return new Ast.ThisReferenceExpression();
                    } else {
                        return new Ast.IdentifierExpression(((ParameterDefinition)operand).Name);
                    }
                case Code.Ldarga:
                    if (methodDef.HasThis && ((ParameterDefinition)operand).Index < 0) {
                        return MakeRef(new Ast.ThisReferenceExpression());
                    } else {
                        return MakeRef(new Ast.IdentifierExpression(((ParameterDefinition)operand).Name));
                    }
                case Code.Ldc_I4:
                case Code.Ldc_I8:
                case Code.Ldc_R4:
                case Code.Ldc_R8:
                    return new Ast.PrimitiveExpression(operand);
                case Code.Ldfld:
                    return arg1.Member(((FieldReference) operand).Name).WithAnnotation(operand);
                case Code.Ldsfld:
                    return AstBuilder.ConvertType(((FieldReference)operand).DeclaringType)
                        .Member(((FieldReference)operand).Name).WithAnnotation(operand);
                case Code.Stfld:
                    return new AssignmentExpression(arg1.Member(((FieldReference) operand).Name).WithAnnotation(operand), arg2);
                case Code.Stsfld:
                    return new AssignmentExpression(
                        AstBuilder.ConvertType(((FieldReference)operand).DeclaringType)
                        .Member(((FieldReference)operand).Name).WithAnnotation(operand),
                        arg1);
                case Code.Ldflda:
                    return MakeRef(arg1.Member(((FieldReference) operand).Name).WithAnnotation(operand));
                case Code.Ldsflda:
                    return MakeRef(
                        AstBuilder.ConvertType(((FieldReference)operand).DeclaringType)
                        .Member(((FieldReference)operand).Name).WithAnnotation(operand));
                case Code.Ldloc:
                    if (operand is ILVariable) {
                        return new Ast.IdentifierExpression(((ILVariable)operand).Name);
                    } else {
                        return new Ast.IdentifierExpression(((VariableDefinition)operand).Name);
                    }
                case Code.Ldloca:
                    if (operand is ILVariable) {
                        return MakeRef(new Ast.IdentifierExpression(((ILVariable)operand).Name));
                    } else {
                        return MakeRef(new Ast.IdentifierExpression(((VariableDefinition)operand).Name));
                    }
                    case Code.Ldnull: return new Ast.NullReferenceExpression();
                    case Code.Ldobj: throw new NotImplementedException();
                    case Code.Ldstr: return new Ast.PrimitiveExpression(operand);
                case Code.Ldtoken:
                    if (operand is Cecil.TypeReference) {
                        return new Ast.TypeOfExpression { Type = operandAsTypeRef }.Member("TypeHandle");
                    } else {
                        throw new NotImplementedException();
                    }
                    case Code.Leave: return null;
                    case Code.Localloc: throw new NotImplementedException();
                    case Code.Mkrefany: throw new NotImplementedException();
                case Code.Newobj:
                    Cecil.TypeReference declaringType = ((MethodReference)operand).DeclaringType;
                    // TODO: Ensure that the corrent overloaded constructor is called
                    if (declaringType is ArrayType) {
                        return new Ast.ArrayCreateExpression {
                            Type = AstBuilder.ConvertType((ArrayType)declaringType),
                            Arguments = args
                        };
                    }
                    return new Ast.ObjectCreateExpression {
                        Type = AstBuilder.ConvertType(declaringType),
                        Arguments = args
                    };
                    case Code.No: throw new NotImplementedException();
                    case Code.Nop: return null;
                    case Code.Pop: return arg1;
                    case Code.Readonly: throw new NotImplementedException();
                    case Code.Refanytype: throw new NotImplementedException();
                    case Code.Refanyval: throw new NotImplementedException();
                    case Code.Ret: {
                        if (methodDef.ReturnType.FullName != Constants.Void) {
                            arg1 = Convert(arg1, methodDef.ReturnType);
                            return new Ast.ReturnStatement { Expression = arg1 };
                        } else {
                            return new Ast.ReturnStatement();
                        }
                    }
                    case Code.Rethrow: return new Ast.ThrowStatement();
                    case Code.Sizeof: return new Ast.SizeOfExpression { Type = AstBuilder.ConvertType(operand as TypeReference) };
                    case Code.Starg: throw new NotImplementedException();
                    case Code.Stloc: {
                        ILVariable locVar = (ILVariable)operand;
                        if (!definedLocalVars.Contains(locVar)) {
                            definedLocalVars.Add(locVar);
                            return new Ast.VariableDeclarationStatement() {
                                Type = locVar.Type != null ? AstBuilder.ConvertType(locVar.Type) : new Ast.PrimitiveType("var"),
                                Variables = new[] { new Ast.VariableInitializer(locVar.Name, arg1) }
                            };
                        } else {
                            return new Ast.AssignmentExpression(new Ast.IdentifierExpression(locVar.Name), arg1);
                        }
                    }
                    case Code.Stobj: throw new NotImplementedException();
                    case Code.Switch: throw new NotImplementedException();
                    case Code.Tail: throw new NotImplementedException();
                    case Code.Throw: return new Ast.ThrowStatement { Expression = arg1 };
                    case Code.Unaligned: throw new NotImplementedException();
                    case Code.Unbox: throw new NotImplementedException();
                    case Code.Unbox_Any: throw new NotImplementedException();
                    case Code.Volatile: throw new NotImplementedException();
                    default: throw new Exception("Unknown OpCode: " + opCode);
            }
        }