예제 #1
0
        protected override IStatement ConvertFor(IForStatement ifs)
        {
            IExpression sizeExpr = Recognizer.LoopSizeExpression(ifs);

            if (sizeExpr is ILiteralExpression)
            {
                int size = (int)((ILiteralExpression)sizeExpr).Value;
                if (size < 20)
                {
                    ConditionBinding binding = GetInitializerBinding(ifs);
                    if (binding.rhs is ILiteralExpression)
                    {
                        int start = (int)((ILiteralExpression)binding.rhs).Value;
                        for (int i = start; i < size; i++)
                        {
                            iterationContext.Add(new ConditionBinding(binding.lhs, Builder.LiteralExpr(i)));
                            IBlockStatement body = ConvertBlock(ifs.Body);
                            context.AddStatementsBeforeCurrent(body.Statements);
                            iterationContext.RemoveAt(iterationContext.Count - 1);
                        }
                        return(null);
                    }
                }
            }
            return(base.ConvertFor(ifs));
        }
 public override IBlockStatement Rewrite(IBlockStatement block)
 {
     while (true)
     {
         var specializedNestedType = this.type as ISpecializedNestedTypeDefinition;
         if (specializedNestedType != null)
         {
             this.type = specializedNestedType.ContainingTypeDefinition;
             //Carry on. At some point, the container must be a generic type instance.
         }
         else
         {
             var genInstance = this.type as IGenericTypeInstance;
             if (genInstance != null)
             {
                 var argEnum = genInstance.GenericArguments.GetEnumerator();
                 var parEnum = genInstance.GenericType.ResolvedType.GenericParameters.GetEnumerator();
                 while (argEnum.MoveNext() && parEnum.MoveNext())
                 {
                     this.genericArgumentsMap.Add(parEnum.Current.InternedKey, argEnum.Current);
                 }
                 return(base.Rewrite(block));
             }
             else
             {
                 Contract.Assume(false); //specialized methods should come either from specialized nested types, or from generic types intances.
                 return(block);
             }
         }
     }
 }
예제 #3
0
        public override void TraverseChildren(IBlockStatement block)
        {
            Contract.Assume(block is BlockStatement);
            var mutableBlock = (BlockStatement)block;

            this.Traverse(mutableBlock.Statements);
            foreach (var pair in this.declaringBlockMap)
            {
                if (pair.Value != mutableBlock)
                {
                    continue;
                }
                var boundExpr = this.closureFieldToLocalOrParameterMap[pair.Key] as BoundExpression;
                if (boundExpr == null)
                {
                    Contract.Assume(false); continue;
                }
                var local = boundExpr.Definition as ILocalDefinition;
                if (local == null)
                {
                    Contract.Assume(false); continue;
                }
                var localDecl = new LocalDeclarationStatement()
                {
                    LocalVariable = local
                };
                mutableBlock.Statements.Insert(0, localDecl);
            }
        }
예제 #4
0
        public override void TraverseChildren(IBlockStatement block)
        {
            this.Traverse(block.Statements);
            BasicBlock b = (BasicBlock)block;

            this.Traverse(b);
        }
예제 #5
0
        public override void TraverseChildren(IBlockStatement block)
        {
            var savedCurrentBlock = this.currentBlock;
            var bb = (BasicBlock)block;

            this.currentBlock = bb;
            while (true)
            {
                var n = bb.Statements.Count;
                if (n == 0)
                {
                    break;
                }
                for (int i = 0; i < n - 1; i++)
                {
                    this.Traverse(bb.Statements[i]);
                }
                var bbb = bb.Statements[n - 1] as BasicBlock;
                if (bbb == null || this.loopHeader == null)
                {
                    this.Traverse(bb.Statements[n - 1]);
                    break;
                }
                bb = bbb;
            }
            this.Traverse(this.currentBlock);
            this.currentBlock = savedCurrentBlock;
        }
        //public override void Visit(ISourceMethodBody methodBody) {
        //  var block = methodBody.Block as BlockStatement;
        //  // TODO: Error if cast fails?

        //  if (block != null) {
        //    var remover = new AnonymousDelegateRemover(this.sink.host, this.PdbReader);
        //    var newTypes = remover.RemoveAnonymousDelegates(methodBody.MethodDefinition, block);
        //  }
        //  base.Visit(methodBody);
        //}

        public override void TraverseChildren(IBlockStatement block)
        {
            foreach (var s in block.Statements)
            {
                this.Traverse(s);
            }
        }
예제 #7
0
 /// <summary>
 /// Visits the specified block.
 /// </summary>
 /// <param name="block">The block.</param>
 public override void Visit(IBlockStatement block)
 {
     if (this.insertAssumeFalseAtLine != null)
     {
         uint startLine;
         uint endLine;
         GetLocationLineSpan(GetPrimarySourceLocationFrom(block.Locations), out startLine, out endLine);
         if (startLine <= this.insertAssumeFalseAtLine.Value &&
             this.insertAssumeFalseAtLine.Value < endLine)
         {
             foreach (IStatement stmt in block.Statements)
             {
                 GetLocationLineSpan(GetPrimarySourceLocationFrom(stmt.Locations), out startLine, out endLine);
                 GetPrimarySourceLocationFrom(stmt.Locations);
                 if (this.insertAssumeFalseAtLine.Value < endLine)
                 {
                     AssumeStatement     assumeFalse = new AssumeStatement();
                     CompileTimeConstant constFalse  = new CompileTimeConstant();
                     constFalse.Value      = false;
                     assumeFalse.Condition = constFalse;
                     this.GetOrCreateStmtListForStmt(stmt).Add(assumeFalse);
                     break;
                 }
             }
         }
     }
     base.Visit(block);
 }
예제 #8
0
        internal void processMethod(IMethodDeclaration method)
        {
            IMethodDeclaration methodDecl = translator.TranslateMethodDeclaration(method);

            if (!(methodDecl is IConstructorDeclaration))
            {
                IBlockStatement body = methodDecl.Body as IBlockStatement;
                if (body != null)
                {
                    mutators       = new Dictionary <IExpression, List <IExpression> >();
                    reportedErrors = new Dictionary <IExpression, bool>();
                    processStatement(body);
                    reportErrors();
                    foreach (IExpression expr in reportedErrors.Keys)
                    {
                        String obj = expr is IFieldReferenceExpression
                            ? ((IFieldReferenceExpression)expr).Field.Name
                            : expr is IVariableReferenceExpression
                              ? ((IVariableReferenceExpression)expr).Variable.Resolve().Name
                              : expr.ToString();
                        messages.Append("Object \"" + obj + "\" is updated in method " + GetMethodName(methodDecl) + " without marking as modified\n");
                    }
                }
            }
        }
예제 #9
0
        public override bool Equals(object obj)
        {
            if (this == obj)
            {
                return(true);
            }

            IBlockStatement statement = obj as IBlockStatement;

            if (statement == null ||
                Statements.Count != statement.Statements.Count)
            {
                return(false);
            }

            for (int i = 0; i < Statements.Count; i++)
            {
                if (!(Statements[i].Equals(statement.Statements[i])))
                {
                    return(false);
                }
            }

            return(true);
        }
        private void parseBlockForEventCancellation(IBlockStatement block, out bool cancels)
        {
            PhoneNavigationCallsTraverser traverser = new PhoneNavigationCallsTraverser(host);

            traverser.Traverse(block);
            cancels = traverser.CancelsEvents;
        }
예제 #11
0
        public override ITypeDeclaration Transform(ITypeDeclaration itd)
        {
            bool useJaggedSubarrayWithMarginal = (this.algorithmDefault is ExpectationPropagation);

            analysis = new VariableAnalysisTransform(useJaggedSubarrayWithMarginal);
            analysis.Context.InputAttributes = context.InputAttributes;
            analysis.Transform(itd);
            context.Results = analysis.Context.Results;
            var itdOut = base.Transform(itd);

            if (context.trackTransform)
            {
                IBlockStatement block = Builder.BlockStmt();
                block.Statements.Add(Builder.CommentStmt("variablesOmittingVariableFactor:"));
                foreach (var ivd in analysis.variablesExcludingVariableFactor)
                {
                    block.Statements.Add(Builder.CommentStmt(ivd.ToString()));
                }
                context.OutputAttributes.Add(itdOut, new DebugInfo()
                {
                    Transform = this,
                    Name      = "analysis",
                    Value     = block
                });
            }
            return(itdOut);
        }
예제 #12
0
 public override void TraverseChildren(IBlockStatement block) {
   base.TraverseChildren(block);
   Contract.Assume(block is BlockStatement);
   var decompiledBlock = (BlockStatement)block;
   var statements = decompiledBlock.Statements;
   for (int i = 0; i < statements.Count-1; i++) {
     var switchInstruction = statements[i] as SwitchInstruction;
     if (switchInstruction == null) continue;
     SwitchStatement result = new SwitchStatement();
     result.Expression = switchInstruction.switchExpression;
     statements[i] = result;
     for (int j = 0, n = switchInstruction.SwitchCases.Count; j < n; j++) {
       CompileTimeConstant caseLabel = new CompileTimeConstant() { Value = j, Type = this.host.PlatformType.SystemInt32 };
       var gotoCaseBody = switchInstruction.SwitchCases[j];
       Contract.Assume(gotoCaseBody != null);
       SwitchCase currentCase = new SwitchCase() { Expression = caseLabel };
       result.Cases.Add(currentCase);
       if (j < n-1) {
         Contract.Assume(switchInstruction.SwitchCases[j+1] != null);
         if (gotoCaseBody.TargetStatement == switchInstruction.SwitchCases[j+1].TargetStatement) continue;
       }
       currentCase.Body.Add(gotoCaseBody);
     }
     if (i == statements.Count-1) return;
     Contract.Assert(i+1 <= statements.Count);
     var gotoStatement = statements[i+1] as IGotoStatement;
     if (gotoStatement != null) {
       SwitchCase defaultCase = new SwitchCase() { }; // Default case is represented by a dummy Expression.
       defaultCase.Body.Add(statements[i + 1]);
       statements.RemoveAt(i + 1);
       result.Cases.Add(defaultCase);
     }
   }
 }
예제 #13
0
        public override void TraverseChildren(IBlockStatement block)
        {
            BasicBlock basicBlock = (BasicBlock)block;
            List <ILocalDefinition> /*?*/ localsInCurrentScope = basicBlock.LocalVariables;

            if (localsInCurrentScope != null)
            {
                this.AddDeclarationsWithInitialValues(localsInCurrentScope, basicBlock);
                List <IStatement> prelude = new List <IStatement>(localsInCurrentScope.Count);
                foreach (ILocalDefinition localDef in localsInCurrentScope)
                {
                    if (this.declaredLocals.ContainsKey(localDef))
                    {
                        continue;
                    }
                    LocalDeclarationStatement localDecl = new LocalDeclarationStatement();
                    localDecl.LocalVariable = localDef;
                    prelude.Add(localDecl);
                }
                if (prelude.Count > 0)
                {
                    basicBlock.Statements.InsertRange(0, prelude); //TODO: use pdb info to insert them in the same order they appear in the source
                }
            }
            this.Traverse(basicBlock.Statements);
        }
예제 #14
0
        public override void TraverseChildren(IBlockStatement block)
        {
            IList <Tuple <IStatement, StaticURIMode, string> > staticNavStmts = new List <Tuple <IStatement, StaticURIMode, string> >();
            IList <IStatement> nonStaticNavStmts = new List <IStatement>();

            foreach (IStatement statement in block.Statements)
            {
                navCallFound    = false;
                navCallIsStatic = false;
                navCallIsBack   = false;
                this.Traverse(statement);
                if (navCallFound)
                {
                    navCallers.Add(methodTraversed);
                    if (navCallIsStatic)
                    {
                        staticNavStmts.Add(new Tuple <IStatement, StaticURIMode, string>(statement, currentStaticMode, unpurifiedFoundURI));
                    }
                    else if (!navCallIsBack)
                    {
                        nonStaticNavStmts.Add(statement);
                    }
                }
            }

            injectNavigationUpdateCode(block, staticNavStmts, nonStaticNavStmts);
        }
        protected override async Task <ImmutableArray <CodeAction> > GetRefactoringsAsync(
            Document document, IParameterSymbol parameter, TMemberDeclarationSyntax memberDeclaration,
            IBlockStatement blockStatementOpt, CancellationToken cancellationToken)
        {
            // Only should provide null-checks for reference types and nullable types.
            if (!parameter.Type.IsReferenceType &&
                !parameter.Type.IsNullable())
            {
                return(ImmutableArray <CodeAction> .Empty);
            }

            var syntaxFacts   = document.GetLanguageService <ISyntaxFactsService>();
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            // Look for an existing "if (p == null)" statement, or "p ?? throw" check.  If we already
            // have one, we don't want to offer to generate a new null check.
            //
            // Note: we only check the top level statements of the block.  I think that's sufficient
            // as this will catch the 90% case, while not being that bad an experience even when
            // people do strange things in their constructors.
            if (blockStatementOpt != null)
            {
                foreach (var statement in blockStatementOpt.Statements)
                {
                    if (IsIfNullCheck(statement, parameter))
                    {
                        return(ImmutableArray <CodeAction> .Empty);
                    }

                    if (ContainsNullCoalesceCheck(
                            syntaxFacts, semanticModel, statement,
                            parameter, cancellationToken))
                    {
                        return(ImmutableArray <CodeAction> .Empty);
                    }
                }
            }

            // Great.  There was no null check.  Offer to add one.
            var result = ArrayBuilder <CodeAction> .GetInstance();

            result.Add(new MyCodeAction(
                           FeaturesResources.Add_null_check,
                           c => AddNullCheckAsync(document, parameter, memberDeclaration, blockStatementOpt, c)));

            // Also, if this was a string, offer to add the special checks to
            // string.IsNullOrEmpty and string.IsNullOrWhitespace.
            if (parameter.Type.SpecialType == SpecialType.System_String)
            {
                result.Add(new MyCodeAction(
                               FeaturesResources.Add_string_IsNullOrEmpty_check,
                               c => AddStringCheckAsync(document, parameter, memberDeclaration, blockStatementOpt, nameof(string.IsNullOrEmpty), c)));

                result.Add(new MyCodeAction(
                               FeaturesResources.Add_string_IsNullOrWhiteSpace_check,
                               c => AddStringCheckAsync(document, parameter, memberDeclaration, blockStatementOpt, nameof(string.IsNullOrWhiteSpace), c)));
            }

            return(result.ToImmutableAndFree());
        }
예제 #16
0
 public override void TraverseChildren(IBlockStatement block) {
   Contract.Assume(block is BlockStatement);
   var decompiledBlock = (BlockStatement)block;
   var statements = decompiledBlock.Statements;
   for (int i = 0; i < statements.Count-3; i++) {
     var gotoCondition = statements[i] as GotoStatement;
     if (gotoCondition == null) continue;
     var gotosThatTarget = this.gotosThatTarget[(uint)gotoCondition.TargetStatement.Label.UniqueKey];
     Contract.Assume(gotosThatTarget != null && gotosThatTarget.Count >= 1);
     if (gotosThatTarget.Count != 1) continue;
     var conditionalGotoBody = LookForCondition(statements, i+1, gotoCondition.TargetStatement);
     if (conditionalGotoBody == null || !(conditionalGotoBody.FalseBranch is EmptyStatement)) continue;
     var gotoBody = conditionalGotoBody.TrueBranch as GotoStatement;
     if (gotoBody == null) continue;
     Contract.Assume(i < statements.Count-3);
     if (!IsOrContainsAsFirstStatement(statements[i+1], gotoBody.TargetStatement)) continue;
     gotosThatTarget.Remove(gotoCondition);
     gotosThatTarget = this.gotosThatTarget[(uint)gotoBody.TargetStatement.Label.UniqueKey];
     Contract.Assume(gotosThatTarget != null && gotosThatTarget.Count >= 1);
     gotosThatTarget.Remove(gotoBody);
     var loopBody = ExtractBlock(statements, i+1, gotoCondition.TargetStatement);
     var whileLoop = new WhileDoStatement() { Body = loopBody, Condition = conditionalGotoBody.Condition };
     Contract.Assume(i < statements.Count);
     statements[i] = whileLoop;
   }
   base.TraverseChildren(block);
 }
예제 #17
0
 private void ProcessBlockStatement(IBlockStatement pStatement)
 {
     foreach (IStatement statement in pStatement.Statements)
     {
         ProcessStatement(statement);
     }
 }
예제 #18
0
        public override void TraverseChildren(IBlockStatement blockStatement)
        {
            base.TraverseChildren(blockStatement);
            Contract.Assume(blockStatement is BlockStatement);
            var block      = (BlockStatement)blockStatement;
            var statements = block.Statements;
            var n          = statements.Count;

            for (int i = 0; i < n; i++)
            {
                var nestedBlock = statements[i] as BlockStatement;
                if (nestedBlock != null)
                {
                    if (nestedBlock.Statements.Count == 1)
                    {
                        var decompiledBlock = nestedBlock as DecompiledBlock;
                        if (decompiledBlock != null && decompiledBlock.IsLexicalScope)
                        {
                            continue;
                        }
                        if (nestedBlock.Statements[0] is ILocalDeclarationStatement)
                        {
                            continue;
                        }
                        statements[i] = nestedBlock.Statements[0];
                    }
                    else if (n == 1)
                    {
                        block.Statements = nestedBlock.Statements;
                        return;
                    }
                }
            }
        }
예제 #19
0
        public override ITypeDeclaration Transform(ITypeDeclaration itd)
        {
            analysis = new ChannelAnalysisTransform();
            analysis.Context.InputAttributes = context.InputAttributes;
            analysis.Transform(itd);
            context.Results = analysis.Context.Results;
            var itdOut = base.Transform(itd);

            if (context.trackTransform && debug)
            {
                IBlockStatement block = Builder.BlockStmt();
                foreach (var entry in analysis.usageInfo)
                {
                    IVariableDeclaration ivd = entry.Key;
                    var info = entry.Value;
                    block.Statements.Add(Builder.CommentStmt(info.ToString()));
                }
                context.OutputAttributes.Add(itdOut, new DebugInfo()
                {
                    Transform = this,
                    Name      = "analysis",
                    Value     = block
                });
            }
            return(itdOut);
        }
예제 #20
0
        public override ITypeDeclaration Transform(ITypeDeclaration itd)
        {
            var analysis = new LocalAnalysisTransform(this.compiler);

            analysis.Context.InputAttributes = context.InputAttributes;
            analysis.Transform(itd);
            context.Results = analysis.Context.Results;
            if (!context.Results.IsSuccess)
            {
                Error("analysis failed");
                return(itd);
            }
            this.localInfoOfStmt = analysis.localInfoOfStmt;
            var itdOut = base.Transform(itd);

            if (context.trackTransform && debug)
            {
                IBlockStatement block = Builder.BlockStmt();
                foreach (var entry in analysis.localInfoOfStmt.Values.SelectMany(dict => dict))
                {
                    var expr = entry.Key;
                    var info = entry.Value;
                    block.Statements.Add(Builder.CommentStmt(expr.ToString() + " " + StringUtil.ToString(info)));
                }
                context.OutputAttributes.Add(itdOut, new DebugInfo()
                {
                    Transform = this,
                    Name      = "analysis",
                    Value     = block
                });
            }
            return(itdOut);
        }
 public static void VisitBlockStatementChildren <TStatement>(
     IBlockStatement <TStatement> blockStatement,
     IGenericStatementVisitor visitor)
     where TStatement : IStatement
 {
     VisitCollection(blockStatement.Statements, visitor);
 }
예제 #22
0
            public override void TraverseChildren(IBlockStatement block)
            {
                Contract.Assume(block is BlockStatement);
                Contract.Assume(this.gotosThatTarget != null);
                var b = (BlockStatement)block;

                for (int i = 0; i < b.Statements.Count; i++)
                {
                    var label = b.Statements[i] as LabeledStatement;
                    if (label != null)
                    {
                        var gotos = this.gotosThatTarget.Find((uint)label.Label.UniqueKey);
                        if (gotos == null || gotos.Count == 0)
                        {
                            b.Statements.RemoveAt(i--);
                        }
                    }
                    else
                    {
                        var gotoStatement = b.Statements[i] as GotoStatement;
                        if (gotoStatement == null || gotoStatement.TargetStatement != this.targetLabel)
                        {
                            continue;
                        }
                        var gotos = this.gotosThatTarget.Find((uint)gotoStatement.TargetStatement.Label.UniqueKey);
                        if (gotos != null)
                        {
                            gotos.Remove(gotoStatement);
                        }
                        b.Statements.RemoveAt(i--);
                    }
                }
                this.Traverse(b.Statements);
            }
예제 #23
0
 public override void VisitBlockStatement <TStatement>(IBlockStatement <TStatement> blockStatement)
 {
     Value = new Statement()
     {
         BlockStatement = new BlockStatementFactory(blockStatement).Value
     };
 }
예제 #24
0
            public static bool IsDeferringCtor(IMethodDefinition method, IBlockStatement body)
            {
                var fcc = new FindCtorCall(method.ContainingType);

                fcc.Traverse(body);
                return(fcc.isDeferringCtor);
            }
예제 #25
0
 public override void TraverseChildren(IBlockStatement block)
 {
     BasicBlock blockStatement = (BasicBlock)block;
       List<IStatement> flatListOfStatements = new List<IStatement>();
       this.Flatten(blockStatement, flatListOfStatements);
       blockStatement.Statements = flatListOfStatements;
 }
예제 #26
0
        public override void TraverseChildren(IBlockStatement block)
        {
            BasicBlock        blockStatement       = (BasicBlock)block;
            List <IStatement> flatListOfStatements = new List <IStatement>();

            this.Flatten(blockStatement, flatListOfStatements);
            blockStatement.Statements = flatListOfStatements;
        }
예제 #27
0
 public override void Visit(IBlockStatement block)
 {
     if (Process(block))
     {
         visitor.Visit(block);
     }
     base.Visit(block);
 }
        private void parseBlockForNavigation(IBlockStatement block, out bool navigates, out ICollection <string> navTargets)
        {
            PhoneNavigationCallsTraverser traverser = new PhoneNavigationCallsTraverser(host);

            traverser.Traverse(block);
            navigates  = traverser.CodeDoesNavigation;
            navTargets = traverser.NavigationTargets;
        }
예제 #29
0
 internal static void WriteBlock(LanguageWriter w, IBlockStatement blockStatement)
 {
     if (blockStatement.Statements.Count == 0)
     {
         return;
     }
     WriteStatementCollection(w, blockStatement.Statements);
 }
예제 #30
0
 public static IBlockStatement RemoveCachedDelegates(IMetadataHost host, IBlockStatement blockStatement, SourceMethodBody sourceMethodBody)
 {
     var finder = new FindAssignmentToCachedDelegateStaticFieldOrLocal(sourceMethodBody);
       finder.Traverse(blockStatement);
       if (finder.cachedDelegateFieldsOrLocals.Count == 0) return blockStatement;
       var mutator = new CachedDelegateRemover(host, finder.cachedDelegateFieldsOrLocals);
       return mutator.Visit(blockStatement);
 }
예제 #31
0
 public override void TraverseChildren(IBlockStatement block)
 {
     base.TraverseChildren(block);
       BasicBlock bb = block as BasicBlock;
       if (bb != null)
     FindPattern(bb.Statements);
       return;
 }
예제 #32
0
        private IExpression /*?*/ GetMonitor(IBlockStatement block, ILocalDefinition local, out ILocalDefinition monitorVar)
        {
            Contract.Ensures(Contract.Result <IExpression>() == null || Contract.ValueAtReturn <ILocalDefinition>(out monitorVar) != null);
            monitorVar = null;
            Contract.Assume(block is BlockStatement);
            var decompiledBlock = (BlockStatement)block;
            var statements      = decompiledBlock.Statements;
            var n = statements.Count;

            if (n < 3)
            {
                return(null);
            }
            var pushStatement = statements[0] as PushStatement;

            if (pushStatement == null)
            {
                return(null);
            }
            var exprStatement1 = statements[1] as ExpressionStatement;

            if (exprStatement1 == null)
            {
                return(null);
            }
            var assignment1 = exprStatement1.Expression as Assignment;

            if (assignment1 == null || !(assignment1.Source is IDupValue))
            {
                return(null);
            }
            monitorVar = assignment1.Target.Definition as ILocalDefinition;
            if (monitorVar == null)
            {
                return(null);
            }
            var exprStatement2 = statements[2] as ExpressionStatement;

            if (exprStatement2 == null)
            {
                return(null);
            }
            var methodCall = exprStatement2.Expression as MethodCall;

            if (methodCall == null)
            {
                return(null);
            }
            if (methodCall.Arguments.Count != 2 || !(methodCall.Arguments[0] is IPopValue))
            {
                return(null);
            }
            if (methodCall.MethodToCall.InternedKey != this.monitorEnter.InternedKey)
            {
                return(null);
            }
            return(pushStatement.ValueToPush);
        }
예제 #33
0
 internal LocalRefVariableStatement(IVariableDeclaration decl, IExpression exp, IBlockStatement block)
 {
     this.decl      = decl;
     this.var_type  = decl.VariableType;
     this.var_name  = decl.Name;
     this.exp       = exp;
     this.block     = block;
     this.labelname = null;
 }
예제 #34
0
        public override void TraverseChildren(IBlockStatement block)
        {
            base.TraverseChildren(block);
            Contract.Assume(block is BlockStatement);
            var decompiledBlock = (BlockStatement)block;
            var statements      = decompiledBlock.Statements;

            for (int i = 0; i < statements.Count - 1; i++)
            {
                var switchInstruction = statements[i] as SwitchInstruction;
                if (switchInstruction == null)
                {
                    continue;
                }
                SwitchStatement result = new SwitchStatement();
                result.Expression = switchInstruction.switchExpression;
                statements[i]     = result;
                for (int j = 0, n = switchInstruction.SwitchCases.Count; j < n; j++)
                {
                    CompileTimeConstant caseLabel = new CompileTimeConstant()
                    {
                        Value = j, Type = this.host.PlatformType.SystemInt32
                    };
                    var gotoCaseBody = switchInstruction.SwitchCases[j];
                    Contract.Assume(gotoCaseBody != null);
                    SwitchCase currentCase = new SwitchCase()
                    {
                        Expression = caseLabel
                    };
                    result.Cases.Add(currentCase);
                    if (j < n - 1)
                    {
                        Contract.Assume(switchInstruction.SwitchCases[j + 1] != null);
                        if (gotoCaseBody.TargetStatement == switchInstruction.SwitchCases[j + 1].TargetStatement)
                        {
                            continue;
                        }
                    }
                    currentCase.Body.Add(gotoCaseBody);
                }
                if (i == statements.Count - 1)
                {
                    return;
                }
                Contract.Assert(i + 1 <= statements.Count);
                var gotoStatement = statements[i + 1] as IGotoStatement;
                if (gotoStatement != null)
                {
                    SwitchCase defaultCase = new SwitchCase()
                    {
                    };                                   // Default case is represented by a dummy Expression.
                    defaultCase.Body.Add(statements[i + 1]);
                    statements.RemoveAt(i + 1);
                    result.Cases.Add(defaultCase);
                }
            }
        }
예제 #35
0
        public override void VisitBlockStatement(IBlockStatement operation)
        {
            foreach (var local in operation.Locals)
            {
                // empty loop body, just want to make sure it won't crash.
            }

            base.VisitBlockStatement(operation);
        }
예제 #36
0
        public override void VisitBlockStatement(IBlockStatement operation)
        {
            foreach (var local in operation.Locals)
            {
                // empty loop body, just want to make sure it won't crash.
            }

            base.VisitBlockStatement(operation);
        }
 public override void TraverseChildren(IBlockStatement block)
 {
     BasicBlock bb = block as BasicBlock;
       if (bb != null) {
     FindPattern(bb.Statements);
     if (bb.Statements.Count > 0) {
       BasicBlock nbb = bb.Statements[bb.Statements.Count-1] as BasicBlock;
       if (nbb != null) this.Traverse(nbb);
     }
       }
 }
예제 #38
0
 public override void TraverseChildren(IBlockStatement block)
 {
     BasicBlock/*?*/ b = (BasicBlock)block;
       var blockTreeAsList = new List<BasicBlock>();
       for (; ; ) {
     blockTreeAsList.Add(b);
     var i = b.Statements.Count-1;
     if (i <= 0) break;
     b = b.Statements[i] as BasicBlock;
     if (b == null) break;
       }
       for (int i = blockTreeAsList.Count-1; i >= 0; i--)
     this.Traverse(blockTreeAsList[i]);
 }
예제 #39
0
    /// <summary>
    /// Given a method definition and a block of statements that represents the Block property of the body of the method,
    /// returns a SourceMethod with a body that no longer has any yield statements or anonymous delegate expressions.
    /// The given block of statements is mutated in place.
    /// </summary>
    public SourceMethodBody GetNormalizedSourceMethodBodyFor(IMethodDefinition method, IBlockStatement body) {
      var finder = new ClosureFinder(method, this.host);
      finder.Traverse(body);

      var privateHelperTypes = new List<ITypeDefinition>();
      if (finder.foundYield) {
        this.isIteratorBody = true;
        body = this.GetNormalizedIteratorBody(body, method, privateHelperTypes);
      }
      SourceMethodBody result = new SourceMethodBody(this.host, this.sourceLocationProvider);
      result.Block = body;
      result.MethodDefinition = method;
      result.IsNormalized = true;
      result.LocalsAreZeroed = true;
      result.PrivateHelperTypes = privateHelperTypes;

      return result;
    }
예제 #40
0
 public override void TraverseChildren(IBlockStatement block)
 {
     BasicBlock basicBlock = (BasicBlock)block;
       List<ILocalDefinition>/*?*/ localsInCurrentScope = basicBlock.LocalVariables;
       if (localsInCurrentScope != null) {
     this.AddDeclarationsWithInitialValues(localsInCurrentScope, basicBlock);
     List<IStatement> prelude = new List<IStatement>(localsInCurrentScope.Count);
     foreach (ILocalDefinition localDef in localsInCurrentScope) {
       if (this.declaredLocals.ContainsKey(localDef)) continue;
       LocalDeclarationStatement localDecl = new LocalDeclarationStatement();
       localDecl.LocalVariable = localDef;
       prelude.Add(localDecl);
     }
     if (prelude.Count > 0)
       basicBlock.Statements.InsertRange(0, prelude); //TODO: use pdb info to insert them in the same order they appear in the source
       }
       this.Traverse(basicBlock.Statements);
 }
예제 #41
0
 public override void TraverseChildren(IBlockStatement block) {
   base.TraverseChildren(block);
   Contract.Assume(block is BlockStatement);
   var decompiledBlock = (BlockStatement)block;
   var statements = decompiledBlock.Statements;
   for (int i = 0; i < statements.Count-1; i++) {
     //TODO: need to deal with patterns where the decl and the assignment are separated.
     var loclDecl = statements[i] as LocalDeclarationStatement;
     if (loclDecl == null) continue;
     var local = loclDecl.LocalVariable;
     if (local.Type.TypeCode != PrimitiveTypeCode.Boolean) continue;
     //if (this.sourceLocationProvider != null) {
     //  bool isCompilerGenerated;
     //  var sourceName = this.sourceLocationProvider.GetSourceNameFor(local, out isCompilerGenerated);
     //  if (!isCompilerGenerated) continue;
     //}
     var tryFinallyStatement = statements[i+1] as TryCatchFinallyStatement;
     if (tryFinallyStatement == null) continue;
     if (tryFinallyStatement.FinallyBody == null || tryFinallyStatement.CatchClauses.Count > 0 || tryFinallyStatement.FaultBody != null) continue;
     ILocalDefinition monitorVar;
     var monitorObject = this.GetMonitor(tryFinallyStatement.TryBody, local, out monitorVar);
     if (monitorObject == null) continue;
     if (!this.FinallyBodyCallsMonitorExit(tryFinallyStatement.FinallyBody, local, monitorVar)) continue;
     this.numberOfAssignmentsToLocal[local]-=2;
     this.numberOfReferencesToLocal[local]-=2;
     this.numberOfAssignmentsToLocal[monitorVar]--;
     this.numberOfReferencesToLocal[monitorVar]--;
     var tryStatements = ((BlockStatement)tryFinallyStatement.TryBody).Statements;
     tryStatements.RemoveRange(0, 3);
     var body = new BlockStatement() { Statements = tryStatements };
     var lockStatement = new LockStatement() { Guard = monitorObject, Body = body, Locations = tryFinallyStatement.Locations };
     statements[i] = lockStatement;
     statements.RemoveAt(i+1);
     if (this.numberOfAssignmentsToLocal[monitorVar] == 0) {
       for (int j = 0; j < statements.Count; j++) {
         var ldecl = statements[j] as LocalDeclarationStatement;
         if (ldecl == null) continue;
         if (ldecl.LocalVariable != monitorVar) continue;
         statements.RemoveAt(j);
         break;
       }
     }
   }
 }
예제 #42
0
파일: Unstacker.cs 프로젝트: xornand/cci
 public static IBlockStatement GetRidOfStack(SourceMethodBody methodBody, IBlockStatement block)
 {
     var me = new Unstacker(methodBody);
     var result = me.Rewrite(block);
     var stmts = new List<IStatement>();
     foreach (var loc in me.createdLocals.Values)
     {
         var decl = new LocalDeclarationStatement()
         {
             InitialValue = null,
             LocalVariable = loc,
         };
         stmts.Add(decl);
     }
     stmts.AddRange(result.Statements);
     var newBlock = new BlockStatement()
     {
         Statements = stmts,
         Locations = new List<ILocation>(result.Locations),
     };
     return newBlock;
 }
예제 #43
0
 public override void TraverseChildren(IBlockStatement blockStatement) {
   base.TraverseChildren(blockStatement);
   Contract.Assume(blockStatement is BlockStatement);
   var block = (BlockStatement)blockStatement;
   var statements = block.Statements;
   var n = statements.Count;
   for (int i = 0; i < n; i++) {
     var nestedBlock = statements[i] as BlockStatement;
     if (nestedBlock != null) {
       if (nestedBlock.Statements.Count == 1) {
         var decompiledBlock = nestedBlock as DecompiledBlock;
         if (decompiledBlock != null && decompiledBlock.IsLexicalScope)
           continue;
         if (nestedBlock.Statements[0] is ILocalDeclarationStatement) continue;
         statements[i] = nestedBlock.Statements[0];
       } else if (n == 1) {
         block.Statements = nestedBlock.Statements;
         return;
       }
     }
   }
 }
예제 #44
0
 public override void TraverseChildren(IBlockStatement blockStatement) {
   base.TraverseChildren(blockStatement);
   Contract.Assume(blockStatement is BlockStatement);
   var block = (BlockStatement)blockStatement;
   int numberOfNonLexicalBlocks = 0;
   int numberOfNonLexicalStatements = 0;
   foreach (var statement in block.Statements) {
     var nestedBlock = statement as DecompiledBlock;
     if (nestedBlock == null) continue;
     if (nestedBlock.IsLexicalScope) continue;
     numberOfNonLexicalBlocks++;
     numberOfNonLexicalStatements += nestedBlock.Statements.Count;
   }
   if (numberOfNonLexicalBlocks == 0) return;
   var flattenedList = new List<IStatement>(block.Statements.Count-numberOfNonLexicalBlocks+numberOfNonLexicalStatements);
   foreach (var statement in block.Statements) {
     var nestedBlock = statement as DecompiledBlock;
     if (nestedBlock == null || nestedBlock.IsLexicalScope)
       flattenedList.Add(statement);
     else
       flattenedList.AddRange(nestedBlock.Statements);
   }
   block.Statements = flattenedList;
 }
예제 #45
0
 public override void TraverseChildren(IBlockStatement block) {
   Contract.Assume(block is BlockStatement);
   var decompiledBlock = (BlockStatement)block;
   var statements = decompiledBlock.Statements;
   for (int i = 0; i < statements.Count-1; i++) {
     IStatement initializer = null;
     var initializerAssignStat = statements[i] as IExpressionStatement;
     if (initializerAssignStat != null) {
       if (!(initializerAssignStat.Expression is IAssignment)) continue;
       initializer = initializerAssignStat;
       i++;
     } else {
       var initialDecl = statements[i] as ILocalDeclarationStatement;
       if (initialDecl == null || initialDecl.InitialValue == null) continue;
       initializer = initialDecl;
       i++;
     }
     var whileLoop = statements[i] as IWhileDoStatement;
     if (whileLoop == null) continue;
     var loopBody = whileLoop.Body as BlockStatement;
     if (loopBody == null) continue;
     var incrementer = FindLastStatement(loopBody) as IExpressionStatement;
     if (incrementer == null) continue;
     var incrementAssignment = incrementer.Expression as IAssignment;
     if (incrementAssignment == null || !(incrementAssignment.Source is IAddition || incrementAssignment.Source is ISubtraction)) continue;
     var forLoop = new ForStatement() { Condition = whileLoop.Condition, Body = loopBody };
     if (initializer != null) {
       statements.RemoveAt(--i);
       forLoop.InitStatements.Add(initializer);
     }
     RemoveLastStatement(loopBody, incrementer);
     forLoop.IncrementStatements.Add(incrementer);
     statements[i] = forLoop;
   }
   base.TraverseChildren(block);
 }
예제 #46
0
 /// <summary>
 /// For an iterator method, find the closure class' MoveNext method and return its body.
 /// </summary>
 /// <param name="iteratorIL">The body of the iterator method, decompiled from the ILs of the iterator body.</param>
 /// <returns>Dummy.MethodBody if <paramref name="iteratorIL"/> does not fit into the code pattern of an iterator method, 
 /// or the body of the MoveNext method of the corresponding closure class if it does.
 /// </returns>
 IMethodBody FindClosureMoveNext(IBlockStatement/*!*/ iteratorIL)
 {
     foreach (var statement in iteratorIL.Statements) {
     ICreateObjectInstance createObjectInstance = GetICreateObjectInstance(statement);
     if (createObjectInstance == null) {
       // If the first statement in the method body is not the creation of iterator closure, return a dummy.
       // Possible corner case not handled: a local is used to hold the constant value for the initial state of the closure.
       return Dummy.MethodBody;
     }
     ITypeReference closureType/*?*/ = createObjectInstance.MethodToCall.ContainingType;
     ITypeReference unspecializedClosureType = GetUnspecializedType(closureType);
     if (!AttributeHelper.Contains(unspecializedClosureType.Attributes, closureType.PlatformType.SystemRuntimeCompilerServicesCompilerGeneratedAttribute))
       return Dummy.MethodBody;
     INestedTypeReference closureTypeAsNestedTypeReference = unspecializedClosureType as INestedTypeReference;
     if (closureTypeAsNestedTypeReference == null) return Dummy.MethodBody;
     ITypeReference unspecializedClosureContainingType = GetUnspecializedType(closureTypeAsNestedTypeReference.ContainingType);
     if (closureType != null && TypeHelper.TypesAreEquivalent(this.ilMethodBody.MethodDefinition.ContainingTypeDefinition, unspecializedClosureContainingType)) {
       IName MoveNextName = this.nameTable.GetNameFor("MoveNext");
       foreach (ITypeDefinitionMember member in closureType.ResolvedType.GetMembersNamed(MoveNextName, false)) {
     IMethodDefinition moveNext = member as IMethodDefinition;
     if (moveNext != null) {
       ISpecializedMethodDefinition moveNextGeneric = moveNext as ISpecializedMethodDefinition;
       if (moveNextGeneric != null)
         moveNext = moveNextGeneric.UnspecializedVersion.ResolvedMethod;
       var body = moveNext.Body;
       var sourceBody = body as SourceMethodBody; //it may already have been decompiled.
       if (sourceBody != null) body = sourceBody.ilMethodBody; //TODO: it would be nice to avoid decompiling it again
       return body;
     }
       }
     }
     return Dummy.MethodBody;
       }
       return Dummy.MethodBody;
 }
예제 #47
0
 private IBlockStatement DecompileMoveNext(IBlockStatement block)
 {
     return new MoveNextDecompiler(this.ilMethodBody.MethodDefinition.ContainingTypeDefinition, this.host).Decompile((BlockStatement)block);
 }
예제 #48
0
 private IBlockStatement AddLocalDeclarationIfNecessary(IBlockStatement block)
 {
     return new ClosureLocalVariableDeclarationAdder(this).Visit(block);
 }
 public override void TraverseChildren(IBlockStatement block) {
   var saved = this.currentBlock;
   this.currentBlock = block;
   base.TraverseChildren(block);
   this.currentBlock = saved;
 }
 public override void TraverseChildren(IBlockExpression blockExpression) {
   var saved = this.currentBlock;
   this.currentBlock = blockExpression.BlockStatement;
   base.TraverseChildren(blockExpression.BlockStatement);
   this.Traverse(blockExpression.Expression);
   this.currentBlock = saved;
 }
예제 #51
0
 /// <summary>
 /// 
 /// </summary>
 public AnonymousDelegate()
 {
     this.body = CodeDummy.Block;
       this.callingConvention = CallingConvention.Default;
       this.parameters = new List<IParameterDefinition>();
       this.returnType = Dummy.TypeReference;
       this.returnValueCustomModifiers = new List<ICustomModifier>();
       this.returnValueIsByRef = false;
 }
예제 #52
0
 public virtual void onASTElement(IBlockStatement block) { }
예제 #53
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="blockStatement"></param>
 public BlockStatement(IBlockStatement blockStatement)
   : base(blockStatement) {
   this.statements = new List<IStatement>(blockStatement.Statements);
   this.useCheckedArithmetic = blockStatement.UseCheckedArithmetic;
 }
        private bool TryFindAssignmentExpression(
            IBlockStatement containingBlock, IIfStatement ifOperation, ISymbol localOrParameter,
            out IExpressionStatement expressionStatement, out IAssignmentExpression assignmentExpression)
        {
            var ifOperationIndex = containingBlock.Statements.IndexOf(ifOperation);

            // walk forward until we find an assignment of this local/parameter into
            // something else.
            for (var i = ifOperationIndex + 1; i < containingBlock.Statements.Length; i++)
            {
                expressionStatement = containingBlock.Statements[i] as IExpressionStatement;
                if (expressionStatement == null)
                {
                    continue;
                }

                assignmentExpression = expressionStatement.Expression as IAssignmentExpression;
                if (assignmentExpression == null)
                {
                    continue;
                }

                if (!TryGetLocalOrParameterSymbol(assignmentExpression.Value, out var assignmentValue))
                {
                    continue;
                }

                if (!Equals(localOrParameter, assignmentValue))
                {
                    continue;
                }

                return true;
            }

            expressionStatement = null;
            assignmentExpression = null;
            return false;
        }
예제 #55
0
 public virtual void VisitBlockStatement(IBlockStatement operation)
 {
     DefaultVisit(operation);
 }
예제 #56
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="blockExpression"></param>
 public BlockExpression(IBlockExpression blockExpression)
     : base(blockExpression)
 {
     this.blockStatement = blockExpression.BlockStatement;
       this.expression = blockExpression.Expression;
 }
예제 #57
0
 /// <summary>
 /// 
 /// </summary>
 public BlockExpression()
 {
     this.blockStatement = CodeDummy.Block;
       this.expression = CodeDummy.Expression;
 }
예제 #58
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="anonymousDelegate"></param>
 public AnonymousDelegate(IAnonymousDelegate anonymousDelegate)
     : base(anonymousDelegate)
 {
     this.body = anonymousDelegate.Body;
       this.callingConvention = anonymousDelegate.CallingConvention;
       this.parameters = new List<IParameterDefinition>(anonymousDelegate.Parameters);
       this.returnType = anonymousDelegate.ReturnType;
       this.returnValueCustomModifiers = new List<ICustomModifier>(anonymousDelegate.ReturnValueCustomModifiers);
       this.returnValueIsByRef = anonymousDelegate.ReturnValueIsByRef;
 }
예제 #59
0
 /// <summary>
 /// Constructs a pair from the arguments.
 /// </summary>
 public MethodContractAndMethodBody(IMethodContract/*?*/ methodContract, IBlockStatement/*?*/ blockStatement) {
   this.methodContract = methodContract;
   this.blockStatement = blockStatement;
 }
예제 #60
0
 public override void TraverseChildren(IBlockStatement block) {
   base.TraverseChildren(block);
   Contract.Assume(block is DecompiledBlock);
   var b = (DecompiledBlock)block;
   int i = 0;
   int n = b.ContainedBlocks.Count;
   for (int j = 0, m = b.Statements.Count; j < m; j++) {
     var nb = b.Statements[j] as DecompiledBlock;
     if (nb == null) continue;
     while (i < n) {
       var bb = b.ContainedBlocks[i++];
       if (DecompiledBlock.GetStartOffset(bb) == nb.StartOffset) continue;
       if (DecompiledBlock.GetStartOffset(bb) >= nb.EndOffset) break;
     }
   }
   while (i < n) {
     var bb = b.ContainedBlocks[i++];
     this.ParseBasicBlock(b.Statements, bb);
   }
 }