Inheritance: Statement, IBlockStatement
        private void AddAlternativeInvocation(BlockStatement block,
            IMethodDefinition fakeMethod, IMethodReference originalCall)
        {
            var context = new ReplacementMethodConstructionContext(host, originalCall, fakeMethod, block, log, null);
            var methodBuilder = context.GetMethodBuilder();

            methodBuilder.BuildMethod();
        }
        public override void BuildMethod()
        {
            AddStatement.DeclareInterceptedType(field.ContainingType.ResolvedType);

            Context.Log.WriteTrace("  Adding: var interceptedField = interceptedType.GetField('{0}');", field.Name.Value);
            Context.Block.Statements.Add(
                Declare.Variable<FieldInfo>("interceptedField").As(
                    Call.VirtualMethod("GetField", typeof (string)).ThatReturns<FieldInfo>().WithArguments(
                        Constant.Of(field.Name.Value)).On("interceptedType"))
            );

            AddStatement.DeclareArgumentsList();

            var funcT = SharpMockTypes.Functions[0];
            var funcActualT = new GenericTypeInstanceReference();
            funcActualT.GenericType = funcT;
            funcActualT.GenericArguments.Add(field.Type);

            var accessor = new AnonymousDelegate();
            accessor.Type = funcActualT;
            accessor.ReturnType = field.Type;
            accessor.CallingConvention = CallingConvention.HasThis;

            var accessorBody = new BlockStatement();
            var returnActualField = new ReturnStatement();
            var actualField = new BoundExpression();
            actualField.Type = field.Type;
            actualField.Definition = field;
            returnActualField.Expression = actualField;
            accessorBody.Statements.Add(returnActualField);
            accessor.Body = accessorBody;

            Context.Block.Statements.Add(
                Declare.Variable("local_0", funcActualT).As(accessor)
            );

            AddStatement.DeclareRegistryInterceptor();
            AddStatement.DeclareInvocation();
            AddStatement.SetArgumentsOnInvocation();
            AddStatement.SetOriginalCallOnInvocation();
            AddStatement.SetTargetOnInvocationToNull();

            Context.Block.Statements.Add(
                Do(Call.PropertySetter<MemberInfo>("OriginalCallInfo").WithArguments("interceptedField").On("invocation"))
            );

            AddStatement.CallShouldInterceptOnInterceptor();
            AddStatement.CallInterceptOnInterceptor();

            Context.Block.Statements.Add(
                Declare.Variable("interceptionResult", field.Type).As(
                    ChangeType.Convert(Call.PropertyGetter<object>("Return").On("invocation")).To(field.Type))
            );

            Context.Block.Statements.Add(Return.Variable(Locals["interceptionResult"]));
        }
        public ReplacementMethodConstructionContext(IMetadataHost host, IMethodReference originalCall, IMethodDefinition fakeMethod, BlockStatement block, ILogger log, IReplaceableReference originalReference)
        {
            this.host = host;
            this.block = block;
            this.log = log;
            this.originalReference = originalReference;
            this.originalCall = originalCall;

            fakeMethodParameters = fakeMethod.Parameters;
            returnType = fakeMethod.Type;
        }
        public ConditionalStatement Else(VoidAction<List<IStatement>> code)
        {
            var blockStatements = new List<IStatement>();
            code(blockStatements);

            var elseBranch = new BlockStatement();
            elseBranch.Statements = blockStatements;

            ifStatement.FalseBranch = elseBranch;
            return ifStatement;
        }
        public ReplacementMethodConstructionContext(IMetadataHost host, IFieldReference originalField, IMethodDefinition fakeMethod, BlockStatement block, bool isAssignment, ILogger log, IReplaceableReference originalReference)
        {
            this.host = host;
            this.block = block;
            this.originalField = originalField;
            this.isAssignment = isAssignment;
            this.log = log;
            this.originalReference = originalReference;

            fakeMethodParameters = fakeMethod.Parameters;
            returnType = fakeMethod.Type;
        }
 static IStatement FindLastStatement(BlockStatement block) {
   IStatement result = null;
   while (block != null) {
     var i = block.Statements.Count-1;
     if (i < 0) return result;
     var nextBlock = block.Statements[i] as BlockStatement;
     if (nextBlock == null) return block.Statements[i];
     if (i > 0) result = block.Statements[i-1];
     block = nextBlock;
   }
   return null;
 }
 static bool RemoveLastStatement(BlockStatement block, IStatement statement) {
   while (block != null) {
     var i = block.Statements.Count-1;
     if (i < 0) return false;
     if (block.Statements[i] == statement) {
       block.Statements.RemoveAt(i);
       return true;
     }
     block = block.Statements[i] as BlockStatement;
   }
   return false;
 }
Exemple #8
0
 internal PatternReplacer(SourceMethodBody sourceMethodBody, BlockStatement block) {
   Contract.Requires(sourceMethodBody != null);
   Contract.Requires(block != null);
   this.host = sourceMethodBody.host; Contract.Assume(this.host != null);
   this.nameTable = this.host.NameTable;
   this.gotosThatTarget = sourceMethodBody.gotosThatTarget; Contract.Assume(this.gotosThatTarget != null);
   this.numberOfAssignmentsToLocal = sourceMethodBody.numberOfAssignmentsToLocal; Contract.Assume(this.numberOfAssignmentsToLocal != null);
   this.numberOfReferencesToLocal = sourceMethodBody.numberOfReferencesToLocal; Contract.Assume(this.numberOfReferencesToLocal != null);
   this.bindingsThatMakeALastUseOfALocalVersion = sourceMethodBody.bindingsThatMakeALastUseOfALocalVersion; Contract.Assume(this.bindingsThatMakeALastUseOfALocalVersion != null);
   this.singleAssignmentReferenceFinder = new SingleAssignmentSingleReferenceFinder(this.bindingsThatMakeALastUseOfALocalVersion, this.numberOfReferencesToLocal);
   this.singleAssignmentLocalReplacer = new SingleAssignmentLocalReplacer(this.host, this.bindingsThatMakeALastUseOfALocalVersion, this.numberOfAssignmentsToLocal);
   this.sourceLocationProvider = sourceMethodBody.sourceLocationProvider;
   this.singleUseExpressionChecker = new SingleUseExpressionChecker();
   Contract.Assume(sourceMethodBody.ilMethodBody != null);
   this.isVoidMethod = sourceMethodBody.ilMethodBody.MethodDefinition.Type.TypeCode == PrimitiveTypeCode.Void;
   while (block != null) {
     var n = block.Statements.Count;
     if (n > 0) {
       var nestedBlock = block.Statements[n-1] as BlockStatement;
       if (nestedBlock != null) { block = nestedBlock; continue; }
     }
     if (n >= 2) { // && sourceMethodBody.ilMethodBody.MethodDefinition.Type.TypeCode != PrimitiveTypeCode.Void) {
       var labeledStatement = block.Statements[n-2] as LabeledStatement;
       if (labeledStatement == null && n >= 3 && block.Statements[n-2] is EmptyStatement) {
         labeledStatement = block.Statements[n-3] as LabeledStatement;
       }
       var returnStatement = block.Statements[n-1] as ReturnStatement;
       if (labeledStatement != null && returnStatement != null) {
         if (sourceMethodBody.ilMethodBody.MethodDefinition.Type.TypeCode != PrimitiveTypeCode.Void) {
           var boundExpression = returnStatement.Expression as BoundExpression;
           if (boundExpression != null) {
             this.returnValueTemp = boundExpression.Definition as ILocalDefinition;
             if (this.returnValueTemp != null) {
               bool isCompilerGenerated = false;
               if (this.sourceLocationProvider != null)
                 this.sourceLocationProvider.GetSourceNameFor(this.returnValueTemp, out isCompilerGenerated);
               if (isCompilerGenerated) {
                 this.labelOfFinalReturn = labeledStatement.Label;
                 this.finalBlock = block;
               } else {
                 this.returnValueTemp = null;
               }
             }
           }
         } else {
           this.labelOfFinalReturn = labeledStatement.Label;
         }
       }
     }
     block = null; //TODO: putting a return here causes Clousot to conclude that the object invariant is never reached.
   }
 }
            public override IMethodBody Rewrite(IMethodBody body)
            {
                var method = body.MethodDefinition;
                _log.Info("Rewriting IMethodBody of: " + method + " Pass: " + MutationTarget.PassInfo);
     
                var newBody = new SourceMethodBody(Host)
                {
                    MethodDefinition = method,
                    LocalsAreZeroed = true
                };
                var block = new BlockStatement();
                newBody.Block = block;

                var replacement = method.ContainingTypeDefinition.Methods.Single(m => m.ToString() == MutationTarget.PassInfo);
                var methodCall = new MethodCall
                    {
                        MethodToCall = replacement,
                        Type = replacement.Type,
                        ThisArgument = new ThisReference() {Type = method.ContainingTypeDefinition}
                    };
                foreach (var param in replacement.Parameters)
                {
                    methodCall.Arguments.Add(new BoundExpression()
                        {
                            Definition = method.Parameters
                                .First(p =>
                                    ((INamedTypeReference)p.Type).Name.Value ==
                                    ((INamedTypeReference)param.Type).Name.Value)
                        });
                    //  methodCall.Arguments.Add(method.Parameters.First(p => new ));
                }

                if (replacement.Type == Host.PlatformType.SystemVoid)
                {
                    block.Statements.Add(new ExpressionStatement
                    {
                        Expression = methodCall
                    });
                    block.Statements.Add(new ReturnStatement());
                }
                else
                {
                    block.Statements.Add(new ReturnStatement
                    {
                        Expression = methodCall
                    });
                   
                }
        
                return newBody;
            }
        public IExpression WithBody(VoidAction<ICodeBuilder> code)
        {
            method.Type = delegateType;
            method.CallingConvention = CallingConvention.HasThis;
            method.ReturnType = returnTypeReference;

            var codeBuilder = new CodeBuilder(host, method.Parameters);
            code(codeBuilder);

            var body = new BlockStatement();
            foreach (var statement in codeBuilder.Statements) body.Statements.Add(statement);
            method.Body = body;

            return method;
        }
Exemple #11
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;
       }
     }
   }
 }
Exemple #12
0
 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;
 }
Exemple #13
0
 private bool ReplaceShortCircuitAnd2(BlockStatement b) {
   Contract.Requires(b != null);
   bool replacedPattern = false;
   var statements = b.Statements;
   for (int i = 0; i < statements.Count-3; i++) {
     var ifStatement = statements[i] as ConditionalStatement;
     if (ifStatement == null) continue;
     var gotoFalseCase = ifStatement.FalseBranch as GotoStatement;
     if (gotoFalseCase == null) continue;
     Contract.Assume(ifStatement.TrueBranch is EmptyStatement);
     var labeledStatement = statements[i+1] as LabeledStatement;
     if (labeledStatement == null) continue;
     var gotos = this.gotosThatTarget[(uint)labeledStatement.Label.UniqueKey];
     if (gotos != null && gotos.Count > 0) continue;
     var ifStatement2 = statements[i+2] as ConditionalStatement;
     if (ifStatement2 == null) continue;
     var gotoTrueCase = ifStatement2.TrueBranch as GotoStatement;
     if (gotoTrueCase == null) continue;
     Contract.Assume(ifStatement2.FalseBranch is EmptyStatement);
     var labeledStatement2 = statements[i+3] as LabeledStatement;
     if (labeledStatement2 == null) continue;
     if (labeledStatement2 == gotoFalseCase.TargetStatement) {
       gotos = this.gotosThatTarget[(uint)labeledStatement2.Label.UniqueKey];
       Contract.Assume(gotos != null && gotos.Count > 0);
       if (gotos.Count > 1) continue;
       var falseConst = new CompileTimeConstant() { Value = false, Type = this.host.PlatformType.SystemBoolean };
       var conditional = new Conditional() { Condition = ifStatement.Condition, ResultIfTrue = ifStatement2.Condition, ResultIfFalse = falseConst, Type = this.host.PlatformType.SystemBoolean };
       ifStatement2.Condition = conditional;
       statements.RemoveRange(i, 2);
       gotos.Remove(gotoFalseCase);
       replacedPattern = true;
     } else {
       if (gotoFalseCase.TargetStatement != gotoTrueCase.TargetStatement) continue;
       //actually have a short circuit or here
       gotos = this.gotosThatTarget[(uint)gotoFalseCase.TargetStatement.Label.UniqueKey];
       Contract.Assume(gotos != null && gotos.Count > 0);
       var trueConst = new CompileTimeConstant() { Value = true, Type = this.host.PlatformType.SystemBoolean };
       var invertedCond = new LogicalNot() { Operand = ifStatement.Condition, Type = this.host.PlatformType.SystemBoolean };
       var conditional = new Conditional() { Condition = invertedCond, ResultIfTrue = trueConst, ResultIfFalse = ifStatement2.Condition, Type = this.host.PlatformType.SystemBoolean };
       ifStatement2.Condition = conditional;
       statements.RemoveRange(i, 2);
       gotos.Remove(gotoFalseCase);
       replacedPattern = true;
     }
   }
   return replacedPattern;
 }
Exemple #14
0
 public override void RewriteChildren(BlockStatement blockStatement) {
   var savedCurrentBlockStatement = this.currentBlockStatement;
   this.currentBlockStatement = blockStatement;
   base.RewriteChildren(blockStatement);
   this.currentBlockStatement = savedCurrentBlockStatement;
 }
 /// <summary>
 /// Rewrites the children of the given statement block.
 /// </summary>
 public override void RewriteChildren(BlockStatement block) {
   if (this.scopesWithCapturedLocals.ContainsKey(block)) {
     this.AllocateClosureFor(block, block.Statements, () => base.RewriteChildren(block));
   } else
     base.RewriteChildren(block);
 }
 public override void RewriteChildren(BlockStatement block) {
   base.RewriteChildren(block);
   if (this.localsToEliminate != null && this.localsToEliminate.Count > 0) {
     var statements = block.Statements;
     var n = statements.Count;
     var j = 0;
     for (int i = 0; i < n; i++) {
       var s = statements[i];
       var localDecl = s as LocalDeclarationStatement;
       if (localDecl != null) {
         if (this.localsToEliminate.Contains(localDecl.LocalVariable)) continue;
       } else {
         var exprSt = s as ExpressionStatement;
         if (exprSt != null) {
           var assign = exprSt.Expression as Assignment;
           if (assign != null && this.localsToEliminate.Contains(assign.Target.Definition)) continue;
         }
       }          
       statements[j++] = s;
     }
     if (j < n) statements.RemoveRange(j, n-j);
   }
   PatternReplacer.ReplacePushPopPattern(block, this.host);
 }
 /// <summary>
 /// Inserts statements into block that will create an instance of the top level closure and initialize it 
 /// with captured parameter values and the "this" value (if captured).
 /// </summary>
 private void InsertStatementsToAllocateAndInitializeTopLevelClosure(BlockStatement body) {
   List<IStatement> statements = new List<IStatement>(this.method.ParameterCount+2+body.Statements.Count);
   IFieldReference fieldReference;
   //initialize local with an instance of the closure class
   statements.Add(
     new LocalDeclarationStatement() {
       LocalVariable = this.currentClosureLocal,
       InitialValue = new CreateObjectInstance() {
         MethodToCall = this.GetReferenceToDefaultConstructor(this.currentClosureInstance),
         Type = this.currentClosureInstance
       }
     });
   //initialize the fields of the closure class with the initial parameter values
   foreach (var parameter in this.method.Parameters) {
     if (!this.fieldReferencesForUseInsideThisMethod.TryGetValue(parameter, out fieldReference)) continue;
     statements.Add(
       new ExpressionStatement() {
         Expression = new Assignment() {
           Target = new TargetExpression() { Instance = this.currentClosureObject, Definition = fieldReference, Type = fieldReference.Type },
           Source = new BoundExpression() { Definition = parameter, Type = parameter.Type },
           Type = parameter.Type
         }
       });
   }
   if (this.method.IsConstructor) {
     var offset = this.GetOffsetOfFirstStatementAfterBaseOrThisConstructorCall(body.Statements);
     statements.AddRange(body.Statements.GetRange(0, offset));
     body.Statements.RemoveRange(0, offset);
   }
   //intialize the this argument field if that exists
   if (this.fieldReferencesForUseInsideThisMethod.TryGetValue(this.method, out fieldReference)) {
     statements.Add(
       new ExpressionStatement() {
         Expression = new Assignment() {
           Target = new TargetExpression() { Instance = this.currentClosureObject, Definition = fieldReference, Type = fieldReference.Type },
           Source = new ThisReference() { Type = fieldReference.Type },
           Type = fieldReference.Type
         }
       });
   }
   statements.AddRange(body.Statements);
   body.Statements = statements;
 }
        public override void BuildMethod()
        {
            AddStatement.DeclareInterceptedType(field.ContainingType.ResolvedType);

            Context.Log.WriteTrace("  Adding: var interceptedField = interceptedType.GetField('{0}');", field.Name.Value);
            Context.Block.Statements.Add(
                Declare.Variable<FieldInfo>("interceptedField").As(
                    Call.VirtualMethod("GetField", typeof (string)).ThatReturns<FieldInfo>().WithArguments(
                        Constant.Of(field.Name.Value)).On("interceptedType"))
            );

            AddStatement.DeclareArgumentsList();
            AddStatement.AddArgumentToList(Params["assignedValue"]);

            var actionT = SharpMockTypes.Actions[1];
            var actionActualT = new GenericTypeInstanceReference();
            actionActualT.GenericType = actionT;
            actionActualT.GenericArguments.Add(field.Type);

            var assignment = new AnonymousDelegate();
            assignment.Type = actionActualT;
            assignment.ReturnType = Context.Host.PlatformType.SystemVoid;
            assignment.CallingConvention = CallingConvention.HasThis;

            var parameterDefinition = new ParameterDefinition();
            parameterDefinition.Index = 0;
            parameterDefinition.Type = field.Type;
            parameterDefinition.Name = Context.Host.NameTable.GetNameFor("alteredValue");
            parameterDefinition.ContainingSignature = assignment;

            assignment.Parameters.Add(parameterDefinition);

            var assignmentBody = new BlockStatement();
            var assignActualField = new ExpressionStatement();
            var actualField = new TargetExpression();
            actualField.Type = field.Type;
            actualField.Definition = field;
            var value = new BoundExpression();
            value.Type = field.Type;
            value.Definition = parameterDefinition;
            var assignValueToField = new Assignment();
            assignValueToField.Source = value;
            assignValueToField.Target = actualField;
            assignValueToField.Type = field.Type;
            assignActualField.Expression = assignValueToField;

            actualField.Type = field.Type;
            actualField.Definition = field;

            assignmentBody.Statements.Add(assignActualField);
            assignmentBody.Statements.Add(new ReturnStatement());
            assignment.Body = assignmentBody;

            Context.Block.Statements.Add(
                Declare.Variable("local_0", actionActualT).As(assignment)
            );

            AddStatement.DeclareRegistryInterceptor();
            AddStatement.DeclareInvocation();
            AddStatement.SetArgumentsOnInvocation();
            AddStatement.SetOriginalCallOnInvocation();
            AddStatement.SetTargetOnInvocationToNull();

            Context.Block.Statements.Add(
                Do(Call.PropertySetter<MemberInfo>("OriginalCallInfo").WithArguments("interceptedField").On("invocation"))
            );

            AddStatement.CallShouldInterceptOnInterceptor();
            AddStatement.CallInterceptOnInterceptor();

            Context.Block.Statements.Add(Return.Void());
        }
Exemple #19
0
 private bool ReplaceShortCircuitAnd4(BlockStatement b) {
   Contract.Requires(b != null);
   bool replacedPattern = false;
   var statements = b.Statements;
   for (int i = 0; i < statements.Count-2; i++) {
     var ifStatement1 = statements[i] as ConditionalStatement;
     if (ifStatement1 == null || !(ifStatement1.FalseBranch is EmptyStatement)) continue;
     var goto1 = ifStatement1.TrueBranch as GotoStatement;
     if (goto1 == null) continue;
     var labStat = statements[i+1] as LabeledStatement;
     if (labStat == null) continue;
     var gotos1 =  this.gotosThatTarget[(uint)labStat.Label.UniqueKey];
     if (gotos1 != null && gotos1.Count > 0) continue;
     var ifStatement2 = statements[i+2] as ConditionalStatement;
     if (ifStatement2 == null) continue;
     if (ifStatement2.TrueBranch is EmptyStatement) {
       var goto2 = ifStatement2.FalseBranch as GotoStatement;
       if (goto2 == null) continue;
       if (goto1.TargetStatement != goto2.TargetStatement) continue;
       var gotos = this.gotosThatTarget[(uint)goto1.TargetStatement.Label.UniqueKey];
       if (gotos == null || gotos.Count == 0) continue;
       var falseConst = new CompileTimeConstant() { Value = false, Type = this.host.PlatformType.SystemBoolean };
       var notCond1 = new LogicalNot() { Operand = ifStatement1.Condition, Type = this.host.PlatformType.SystemBoolean };
       var conditional = new Conditional() { Condition = notCond1, ResultIfTrue = ifStatement2.Condition, ResultIfFalse = falseConst, Type = this.host.PlatformType.SystemBoolean };
       ifStatement2.Condition = conditional;
       statements.RemoveRange(i, 2);
       gotos.Remove(goto1);
       replacedPattern = true;
     } else if (ifStatement2.FalseBranch is EmptyStatement) {
       var goto2 = ifStatement2.TrueBranch as GotoStatement;
       if (goto2 == null) continue;
       if (goto1.TargetStatement != goto2.TargetStatement) continue;
       var gotos = this.gotosThatTarget[(uint)goto1.TargetStatement.Label.UniqueKey];
       if (gotos == null || gotos.Count == 0) continue;
       var trueConst = new CompileTimeConstant() { Value = true, Type = this.host.PlatformType.SystemBoolean };
       var cond1 = ifStatement1.Condition;
       var conditional = new Conditional() { Condition = cond1, ResultIfTrue = trueConst, ResultIfFalse = ifStatement2.Condition, Type = this.host.PlatformType.SystemBoolean };
       ifStatement2.Condition = conditional;
       statements.RemoveRange(i, 2);
       gotos.Remove(goto1);
       replacedPattern = true;
     }
   }
   return replacedPattern;
 }
        private SourceMethodBody GetBody(IMethodDefinition method, IMethodReference originalCall)
        {
            var body = new SourceMethodBody(host, null, null);
            body.MethodDefinition = method;
            body.LocalsAreZeroed = true;

            var block = new BlockStatement();
            body.Block = block;

            AddAlternativeInvocation(block, method, originalCall);

            return body;
        }
Exemple #21
0
 private bool ReplaceShortCircuitAnd5(BlockStatement b) {
   Contract.Requires(b != null);
   bool replacedPattern = false;
   var statements = b.Statements;
   for (int i = 0; i < statements.Count; i++) {
     var ifStatement = statements[i] as ConditionalStatement;
     if (ifStatement == null) continue;
     var pushTrue = ifStatement.TrueBranch as IPushStatement;
     if (pushTrue == null) {
       var trueBlock = ifStatement.TrueBranch as BlockStatement;
       if (trueBlock != null && trueBlock.Statements.Count == 1)
         pushTrue = trueBlock.Statements[0] as IPushStatement;
     }
     if (pushTrue == null || pushTrue.ValueToPush.Type.TypeCode != PrimitiveTypeCode.Boolean) continue;
     var pushFalse = ifStatement.FalseBranch as IPushStatement;
     if (pushFalse == null) {
       var falseBlock = ifStatement.FalseBranch as BlockStatement;
       if (falseBlock != null && falseBlock.Statements.Count == 1)
         pushFalse = falseBlock.Statements[0] as IPushStatement;
     }
     if (pushFalse == null) continue;
     var falseCaseVal = pushFalse.ValueToPush as CompileTimeConstant;
     if (falseCaseVal == null || !(falseCaseVal.Value is int)) continue;
     if (0 != (int)falseCaseVal.Value) continue;
     var falseConst = new CompileTimeConstant() { Value = false, Type = this.host.PlatformType.SystemBoolean };
     statements[i] = new PushStatement() {
       ValueToPush = new Conditional() {
         Condition = ifStatement.Condition, ResultIfTrue = pushTrue.ValueToPush,
         ResultIfFalse = falseConst, Type = pushTrue.ValueToPush.Type
       }
     };
     replacedPattern = true;
   }
   return replacedPattern;
 }
Exemple #22
0
        private void injectNavigationUpdateCode(IBlockStatement block, IEnumerable <Tuple <IStatement, StaticURIMode, string> > staticStmts, IEnumerable <IStatement> nonStaticStmts)
        {
            // TODO Here there is the STRONG assumption that a given method will only navigate at most once per method call
            // TODO (or at most will re-navigate to the same page). Quick "page flipping" on the same method
            // TODO would not be captured correctly
            Microsoft.Cci.MutableCodeModel.BlockStatement mutableBlock = block as Microsoft.Cci.MutableCodeModel.BlockStatement;

            foreach (IStatement stmt in nonStaticStmts)
            {
                int ndx = mutableBlock.Statements.ToList().IndexOf(stmt);
                if (ndx == -1)
                {
                    // can't be
                    throw new IndexOutOfRangeException("Statement must exist in original block");
                }

                Assignment currentURIAssign = new Assignment()
                {
                    Source = new CompileTimeConstant()
                    {
                        Type  = host.PlatformType.SystemString,
                        Value = PhoneCodeHelper.BOOGIE_DO_HAVOC_CURRENTURI,
                    },
                    Type   = host.PlatformType.SystemString,
                    Target = new TargetExpression()
                    {
                        Type = host.PlatformType.SystemString,
                        // TODO unify code for current uri fieldreference
                        Definition = new FieldReference()
                        {
                            ContainingType = PhoneCodeHelper.instance().getMainAppTypeReference(),
                            IsStatic       = true,
                            Type           = host.PlatformType.SystemString,
                            Name           = host.NameTable.GetNameFor(PhoneCodeHelper.IL_CURRENT_NAVIGATION_URI_VARIABLE),
                            InternFactory  = host.InternFactory,
                        },
                    },
                };
                Statement uriInitStmt = new ExpressionStatement()
                {
                    Expression = currentURIAssign,
                };
                mutableBlock.Statements.Insert(ndx + 1, uriInitStmt);
            }


            foreach (Tuple <IStatement, StaticURIMode, string> entry in staticStmts)
            {
                int ndx = mutableBlock.Statements.ToList().IndexOf(entry.Item1);
                if (ndx == -1)
                {
                    // can't be
                    throw new IndexOutOfRangeException("Statement must exist in original block");
                }

                Assignment currentURIAssign = new Assignment()
                {
                    Source = new CompileTimeConstant()
                    {
                        Type  = host.PlatformType.SystemString,
                        Value = UriHelper.getURIBase(entry.Item3).ToLower(),
                    },
                    Type   = host.PlatformType.SystemString,
                    Target = new TargetExpression()
                    {
                        Type = host.PlatformType.SystemString,
                        // TODO unify code for current uri fieldreference
                        Definition = new FieldReference()
                        {
                            ContainingType = PhoneCodeHelper.instance().getMainAppTypeReference(),
                            IsStatic       = true,
                            Type           = host.PlatformType.SystemString,
                            Name           = host.NameTable.GetNameFor(PhoneCodeHelper.IL_CURRENT_NAVIGATION_URI_VARIABLE),
                            InternFactory  = host.InternFactory,
                        },
                    },
                };
                Statement uriInitStmt = new ExpressionStatement()
                {
                    Expression = currentURIAssign,
                };
                mutableBlock.Statements.Insert(ndx + 1, uriInitStmt);
            }
        }
Exemple #23
0
 private static void RemoveLastGoto(BlockStatement block) {
   Contract.Requires(block != null);
   var n = block.Statements.Count;
   if (n == 0) return;
   var lastStatement = block.Statements[n-1];
   var lastGoto = lastStatement as GotoStatement;
   if (lastGoto != null) {
     block.Statements.RemoveAt(n-1);
     return;
   }
   var lastBlock = lastStatement as BlockStatement;
   if (lastBlock == null) return;
   RemoveLastGoto(lastBlock);
 }
    /// <summary>
    /// When given a method definition and a block of statements that represents the Block property of the body of the method
    /// this method returns a semantically equivalent SourceMethod with a body that no longer has any anonymous delegate expressions.
    /// The given block of statements is mutated in place.
    /// Any types that get defined in order to implement the body semantics are returned (null if no such types are defined).
    /// </summary>
    /// <param name="method">The method containing the block that is to be rewritten.</param>
    /// <param name="body">The block to be rewritten. 
    /// The entire tree rooted at the block must be mutable and the nodes must not be shared with anything else.</param>
    public ICollection<ITypeDefinition>/*?*/ RemoveAnonymousDelegates(IMethodDefinition method, BlockStatement body) {
      this.method = method;
      var finder = new CapturedParameterAndLocalFinder();
      finder.TraverseChildren(body);
      this.fieldReferencesForUseInsideAnonymousMethods = finder.captures;
      this.anonymousDelegatesThatCaptureLocalsOrParameters = finder.anonymousDelegatesThatCaptureLocalsOrParameters;
      this.anonymousDelegatesThatCaptureThis = finder.anonymousDelegatesThatCaptureThis;
      finder = null;
      var blockFinder = new ScopesWithCapturedLocalsFinder(this.fieldReferencesForUseInsideAnonymousMethods);
      blockFinder.TraverseChildren(body);
      this.scopesWithCapturedLocals = blockFinder.scopesWithCapturedLocals;
      blockFinder = null;
      this.fieldReferencesForUseInsideThisMethod = new Dictionary<object, IFieldReference>(this.fieldReferencesForUseInsideAnonymousMethods);

      this.GenerateTopLevelClosure();
      if (this.currentClosureClass != null) {
        //declare a local to keep the parameter closure class
        var closureLocal = new LocalDefinition() { Type = this.currentClosureInstance, Name = this.host.NameTable.GetNameFor("CS$<>8__locals"+this.closureClasses.Count) };
        this.currentClosureLocal = closureLocal;
        this.currentClosureObject = new BoundExpression() { Definition = closureLocal, Type = closureLocal.Type };
        this.closureLocalInstances = new List<IExpression>();
        this.closureLocalInstances.Add(this.currentClosureObject);
        this.scopesWithCapturedLocals.Remove(body); //otherwise it will introduce its own closure class if any of its locals were captured.
        this.RewriteChildren(body);
        //do this after rewriting so that parameter references are not rewritten into closure field references.
        this.InsertStatementsToAllocateAndInitializeTopLevelClosure(body);
      } else {
        this.RewriteChildren(body);
      }
      return this.closureClasses == null ? null : this.closureClasses.AsReadOnly();
    }
Exemple #25
0
 private static GotoStatement/*?*/ ReturnLastGoto(BlockStatement block) {
   Contract.Requires(block != null);
   var n = block.Statements.Count;
   if (n == 0) return null;
   var lastStatement = block.Statements[n-1];
   var lastGoto = lastStatement as GotoStatement;
   if (lastGoto != null) return lastGoto;
   var lastBlock = lastStatement as BlockStatement;
   if (lastBlock == null) return null;
   return ReturnLastGoto(lastBlock);
 }
    /// <summary>
    /// Creates a new nested type definition with a default constructor and no other members and adds it to this.closureClasses.
    /// If this.method is generic, then the closure class is generic as well, with the same
    /// number of type parameters (constrained in the same way) as the generic method.
    /// Initializes this.currentClosure, this.currentClosureInstance and this.currentClosureSelfInstance.
    /// </summary>
    private void CreateClosureClass() {
      if (this.closureClasses == null) this.closureClasses = new List<ITypeDefinition>();
      NestedTypeDefinition closure = new NestedTypeDefinition();
      var containingType = this.method.ContainingTypeDefinition;
      closure.Name = this.host.NameTable.GetNameFor("<"+this.method.Name+">c__DisplayClass"+closure.GetHashCode());
      closure.Attributes = new List<ICustomAttribute>(1) { this.compilerGenerated };
      closure.BaseClasses = new List<ITypeReference>(1) { this.host.PlatformType.SystemObject };
      closure.ContainingTypeDefinition = containingType;
      closure.Fields = new List<IFieldDefinition>();
      closure.InternFactory = this.host.InternFactory;
      closure.IsBeforeFieldInit = true;
      closure.IsClass = true;
      closure.IsSealed = true;
      closure.Layout = LayoutKind.Auto;
      closure.Methods = new List<IMethodDefinition>();
      closure.StringFormat = StringFormatKind.Ansi;
      closure.Visibility = TypeMemberVisibility.Private;
      this.closureClasses.Add(closure);
      this.currentClosureClass = closure;

      //generics
      if (this.method.IsGeneric) {
        Dictionary<ushort, IGenericParameterReference> genericMethodParameterMap = new Dictionary<ushort, IGenericParameterReference>();
        this.genericMethodParameterMap = genericMethodParameterMap;
        bool foundConstraints = false;
        var genericTypeParameters = new List<IGenericTypeParameter>(this.method.GenericParameterCount);
        closure.GenericParameters = genericTypeParameters;
        foreach (var genericMethodParameter in this.method.GenericParameters) {
          var copyOfGenericMethodParameter = this.copier.Copy(genericMethodParameter); //so that we have mutable constraints to rewrite
          var genericTypeParameter = new GenericTypeParameter();
          genericTypeParameter.Copy(copyOfGenericMethodParameter, this.host.InternFactory);
          genericTypeParameter.DefiningType = closure;
          if (genericTypeParameter.Constraints != null && genericTypeParameter.Constraints.Count > 0) foundConstraints = true;
          genericTypeParameters.Add(genericTypeParameter);
          genericMethodParameterMap.Add(copyOfGenericMethodParameter.Index, genericTypeParameter);
        }
        if (foundConstraints) {
          //Fix up any self references that might lurk inside constraints.
          closure.GenericParameters = new GenericParameterRewriter(this.host, genericMethodParameterMap).Rewrite(genericTypeParameters);
        }
        var instanceType = closure.InstanceType;
        var genericArguments = IteratorHelper.GetConversionEnumerable<IGenericMethodParameter, ITypeReference>(this.method.GenericParameters);
        this.currentClosureInstance = new Immutable.GenericTypeInstanceReference(instanceType.GenericType, genericArguments, this.host.InternFactory);
        this.currentClosureSelfInstance = instanceType;
      } else {
        //if any of the containing types are generic, we need an instance or a specialized nested type.
        this.currentClosureInstance = NestedTypeDefinition.SelfInstance(closure, this.host.InternFactory);
        this.currentClosureSelfInstance = this.currentClosureInstance;
      }

      //default constructor
      var block = new BlockStatement();
      block.Statements.Add(
        new ExpressionStatement() {
          Expression = new MethodCall() {
            ThisArgument = new ThisReference() { Type = this.currentClosureSelfInstance },
            MethodToCall = this.objectCtor,
            Type = this.host.PlatformType.SystemVoid
          }
        }
      );

      var constructorBody = new SourceMethodBody(this.host, this.sourceLocationProvider) {
        LocalsAreZeroed = true,
        IsNormalized = true,
        Block = block
      };

      var defaultConstructor = new MethodDefinition() {
        Body = constructorBody,
        ContainingTypeDefinition = closure,
        CallingConvention = CallingConvention.HasThis,
        InternFactory = this.host.InternFactory,
        IsCil = true,
        IsHiddenBySignature = true,
        IsRuntimeSpecial = true,
        IsSpecialName = true,
        Name = this.host.NameTable.Ctor,
        Type = this.host.PlatformType.SystemVoid,
        Visibility = TypeMemberVisibility.Public,
      };
      constructorBody.MethodDefinition = defaultConstructor;
      closure.Methods.Add(defaultConstructor);

    }
Exemple #27
0
 /// <summary>
 /// Visits the specified block.
 /// </summary>
 /// <param name="block">The block.</param>
 public override void Visit(IBlockStatement block)
 {
     BlockStatement mutableBlockStatement = new BlockStatement(block);
     this.resultStatement = this.myCodeCopier.DeepCopy(mutableBlockStatement);
 }
 /// <summary>
 /// Rewrites the given assignment expression.
 /// </summary>
 public override IExpression Rewrite(IAssignment assignment) {
   var targetInstance = assignment.Target.Instance;
   var result = base.Rewrite(assignment);
   if (targetInstance == null && assignment.Target.Instance != null) {
     //The target now pushes something onto the stack that was not there before the rewrite.
     //It the right hand side uses the stack, then it will not see the stack it expected.
     //If so, we need to evaluate the right handside and squirrel it away in a temp before executing
     //the actual assignment.
     var popFinder = new PopFinder();
     popFinder.Traverse(assignment.Source);
     if (popFinder.foundAPop) {
       var temp = new LocalDefinition() { Name = this.host.NameTable.GetNameFor("PopTemp"+this.popTempCounter++), Type = assignment.Source.Type };
       var localDeclarationStatement = new LocalDeclarationStatement() { LocalVariable = temp, InitialValue = assignment.Source };
       var blockStatement = new BlockStatement();
       blockStatement.Statements.Add(localDeclarationStatement);
       Contract.Assume(assignment is Assignment);
       ((Assignment)assignment).Source = new BoundExpression() { Definition = temp, Type = temp.Type };
       return new BlockExpression() { BlockStatement = blockStatement, Expression = assignment, Type = assignment.Type };
     }        
   }
   return result;
 }
Exemple #29
0
 /// <summary>
 /// Visits the specified block statement.
 /// </summary>
 /// <param name="blockStatement">The block statement.</param>
 /// <returns></returns>
 protected virtual IBlockStatement DeepCopy(BlockStatement blockStatement)
 {
     blockStatement.Statements = Substitute(blockStatement.Statements);
       return blockStatement;
 }
Exemple #30
0
 private IBlockStatement DuplicateMoveNextForIteratorMethod(BlockStatement rootBlock)
 {
     return MoveNextToIteratorBlockTransformer.Transform(iteratorMethodBody.MethodDefinition, this.ilMethodBody.MethodDefinition, rootBlock, this.host);
 }
 public static IBlockStatement MkBlockStatement(IStatement statement) {
   var block = statement as IBlockStatement;
   if (block == null) {
     block = new BlockStatement() { Statements = new List<IStatement> { statement }, };
   }
   return block;
 }