public override IStatement Rewrite(IConditionalStatement conditionalStatement) { var result = base.Rewrite(conditionalStatement); var mutableConditionalStatement = result as ConditionalStatement; if (mutableConditionalStatement == null) { return(result); } var expressionPushedByTrueBranch = GetPushedExpressionFrom(conditionalStatement.TrueBranch); var expressionPushedByFalseBranch = GetPushedExpressionFrom(conditionalStatement.FalseBranch); if (expressionPushedByFalseBranch != null && expressionPushedByTrueBranch != null) { return(new PushStatement() { ValueToPush = TypeInferencer.FixUpType(new Conditional() { Condition = conditionalStatement.Condition, ResultIfFalse = expressionPushedByFalseBranch, ResultIfTrue = expressionPushedByTrueBranch }), Locations = mutableConditionalStatement.Locations }); } return(result); }
private void ProcessConditionalStatement(IConditionalStatement pStatement) { if (mCurrentBlock.Terminated) { mCurrentBlock = CreateBlock(CreateLabel()); } HLLocation locationCondition = ProcessExpression(pStatement.Condition); HLInstructionBlock blockParent = mCurrentBlock; HLInstructionBlock blockTrueStart = CreateBlock(CreateLabel()); mCurrentBlock = blockTrueStart; ProcessStatement(pStatement.TrueBranch); HLInstructionBlock blockTrueEnd = mCurrentBlock; HLInstructionBlock blockFalseStart = CreateBlock(CreateLabel()); mCurrentBlock = blockFalseStart; ProcessStatement(pStatement.FalseBranch); HLInstructionBlock blockFalseEnd = mCurrentBlock; blockParent.EmitBranch(locationCondition, blockTrueStart.StartLabel, blockFalseStart.StartLabel); if (!blockTrueEnd.Terminated || !blockFalseEnd.Terminated) { mCurrentBlock = CreateBlock(CreateLabel()); blockTrueEnd.Terminate(mCurrentBlock.StartLabel); blockFalseEnd.Terminate(mCurrentBlock.StartLabel); } }
public override void TraverseChildren(IConditionalStatement conditionalStatement) { base.TraverseChildren(conditionalStatement); var condStat = (ConditionalStatement)conditionalStatement; condStat.Condition = ConvertToBoolean(condStat.Condition); }
public override void Visit(IConditionalStatement conditionalStatement) { if (Process(conditionalStatement)) { visitor.Visit(conditionalStatement); } base.Visit(conditionalStatement); }
public override void TraverseChildren(IGotoStatement gotoStatement) { if (gotoStatement == this.backwardsBranch) { if (this.currentIf != null && this.currentIf.TrueBranch == this.currentBlock && this.currentIf.FalseBranch is EmptyStatement) { this.ifContainingBackwardsBranch = this.currentIf; this.blockContainingIfContainingBackwardsBranch = this.blockContainingCurrentIf; } } this.gotosAlreadyTraversed.Add(gotoStatement); base.TraverseChildren(gotoStatement); }
/// <summary> /// /// </summary> /// <remarks>(mschaef) Works, but still a stub</remarks> /// <param name="conditionalStatement"></param> public override void TraverseChildren(IConditionalStatement conditionalStatement) { StatementTraverser thenTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext); StatementTraverser elseTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext); ExpressionTraverser condTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext); if (this.sink.Options.instrumentBranches) { var tok = conditionalStatement.Token(); thenTraverser.StmtBuilder.Add( new Bpl.AssumeCmd(tok, Bpl.Expr.True, new Bpl.QKeyValue(Bpl.Token.NoToken, "breadcrumb", new List <object> { Bpl.Expr.Literal(this.sink.UniqueNumberAcrossAllAssemblies) }, null)) ); elseTraverser.StmtBuilder.Add( new Bpl.AssumeCmd(tok, Bpl.Expr.True, new Bpl.QKeyValue(Bpl.Token.NoToken, "breadcrumb", new List <object> { Bpl.Expr.Literal(this.sink.UniqueNumberAcrossAllAssemblies) }, null)) ); } condTraverser.Traverse(conditionalStatement.Condition); thenTraverser.Traverse(conditionalStatement.TrueBranch); elseTraverser.Traverse(conditionalStatement.FalseBranch); Bpl.Expr conditionExpr = condTraverser.TranslatedExpressions.Pop(); Bpl.Type conditionType = this.sink.CciTypeToBoogie(conditionalStatement.Condition.Type); if (conditionType == this.sink.Heap.RefType) { conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Ident(this.sink.Heap.NullRef)); } else if (conditionType == Bpl.Type.Int) { conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Literal(0)); } else { System.Diagnostics.Debug.Assert(conditionType == Bpl.Type.Bool); } Bpl.IfCmd ifcmd = new Bpl.IfCmd(conditionalStatement.Token(), conditionExpr, thenTraverser.StmtBuilder.Collect(conditionalStatement.TrueBranch.Token()), null, elseTraverser.StmtBuilder.Collect(conditionalStatement.FalseBranch.Token()) ); StmtBuilder.Add(ifcmd); }
public override void TraverseChildren(IConditionalStatement conditionalStatement) { sourceEmitterOutput.Write("if (", true); this.Traverse(conditionalStatement.Condition); sourceEmitterOutput.Write(")"); if (conditionalStatement.TrueBranch is IBlockStatement) this.Traverse(conditionalStatement.TrueBranch); else { PrintToken(CSharpToken.NewLine); sourceEmitterOutput.IncreaseIndent(); this.Traverse(conditionalStatement.TrueBranch); sourceEmitterOutput.DecreaseIndent(); } if (!(conditionalStatement.FalseBranch is IEmptyStatement)) { this.sourceEmitterOutput.Write("else", true); this.Traverse(conditionalStatement.FalseBranch); } }
public override void TraverseChildren(ILabeledStatement labeledStatement) { if (this.loopHeader == null) { List <IGotoStatement> predecessors; if (this.predecessors.TryGetValue(labeledStatement, out predecessors)) { if (predecessors.Count == 1 && !this.gotosAlreadyTraversed.Contains(predecessors[0])) { this.blockContainingLoopHeader = this.currentBlock; this.loopHeader = labeledStatement; this.backwardsBranch = predecessors[0]; this.ifContainingBackwardsBranch = null; } } } base.TraverseChildren(labeledStatement); }
public override IStatement Rewrite(IConditionalStatement conditionalStatement) { var condition = conditionalStatement.Condition; var logicalNot = condition as ILogicalNot; if (logicalNot != null) condition = logicalNot.Operand; var equal = condition as IEquality; if (equal != null && equal.RightOperand is IDefaultValue) condition = equal.LeftOperand; var boundExpression = condition as IBoundExpression; if (boundExpression != null) { var locations = conditionalStatement.Locations; var fieldReference = boundExpression.Definition as IFieldReference; if (fieldReference != null) { if (this.delegatesCachedInFields != null && this.delegatesCachedInFields.Find(fieldReference.InternedKey) != null) return CodeDummy.Block; } else if (this.delegatesCachedInLocals != null) { var local = boundExpression.Definition as LocalDefinition; if (local != null && this.delegatesCachedInLocals.ContainsKey(local)) return CodeDummy.Block; } } return base.Rewrite(conditionalStatement); }
public override IStatement Rewrite(IConditionalStatement conditionalStatement) { var condition = conditionalStatement.Condition; var logicalNot = condition as ILogicalNot; if (logicalNot != null) { condition = logicalNot.Operand; } var equal = condition as IEquality; if (equal != null && equal.RightOperand is IDefaultValue) { condition = equal.LeftOperand; } var boundExpression = condition as IBoundExpression; if (boundExpression != null) { var locations = conditionalStatement.Locations; var fieldReference = boundExpression.Definition as IFieldReference; if (fieldReference != null) { if (this.delegatesCachedInFields != null && this.delegatesCachedInFields.Find(fieldReference.InternedKey) != null) { return(CodeDummy.Block); } } else if (this.delegatesCachedInLocals != null) { var local = boundExpression.Definition as LocalDefinition; if (local != null && this.delegatesCachedInLocals.ContainsKey(local)) { return(CodeDummy.Block); } } } return(base.Rewrite(conditionalStatement)); }
public override void TraverseChildren(IConditionalStatement conditionalStatement) { sourceEmitterOutput.Write("If ", true); this.Traverse(conditionalStatement.Condition); sourceEmitterOutput.WriteLine(" Then"); if (conditionalStatement.TrueBranch is IBlockStatement) { this.Traverse(conditionalStatement.TrueBranch); } else { PrintToken(VBToken.NewLine); sourceEmitterOutput.IncreaseIndent(); this.Traverse(conditionalStatement.TrueBranch); sourceEmitterOutput.DecreaseIndent(); } if (!(conditionalStatement.FalseBranch is IEmptyStatement)) { this.sourceEmitterOutput.Write("else", true); this.Traverse(conditionalStatement.FalseBranch); } }
public override void TraverseChildren(IConditionalStatement conditionalStatement) { Result++; base.TraverseChildren(conditionalStatement); }
public void Visit(IConditionalStatement conditionalStatement) { throw new NotImplementedException(); }
/// <summary> /// /// </summary> /// <param name="conditionalStatement"></param> public ConditionalStatement(IConditionalStatement conditionalStatement) : base(conditionalStatement) { this.condition = conditionalStatement.Condition; this.falseBranch = conditionalStatement.FalseBranch; this.trueBranch = conditionalStatement.TrueBranch; }
public void Visit(IConditionalStatement conditionalStatement) { this.traverser.Traverse(conditionalStatement); }
public void Visit(IConditionalStatement conditionalStatement) { Contract.Requires(conditionalStatement != null); throw new NotImplementedException(); }
public override void Visit(IConditionalStatement conditionalStatement) { allElements.Add(new InvokInfo(Traverser, "IConditionalStatement", conditionalStatement)); }
/// <summary> /// Traverses the conditional statement. /// </summary> public void Traverse(IConditionalStatement conditionalStatement) { Contract.Requires(conditionalStatement != null); if (this.preorderVisitor != null) this.preorderVisitor.Visit(conditionalStatement); if (this.StopTraversal) return; this.TraverseChildren(conditionalStatement); if (this.StopTraversal) return; if (this.postorderVisitor != null) this.postorderVisitor.Visit(conditionalStatement); }
public virtual void onASTElement(IConditionalStatement conditionalStatement) { }
public override void TraverseChildren(IConditionalStatement conditionalStatement) { this.currentIf = conditionalStatement; this.blockContainingCurrentIf = this.currentBlock; base.TraverseChildren(conditionalStatement); }
public override void Visit(IConditionalStatement conditionalStatement) { if(Process(conditionalStatement)){visitor.Visit(conditionalStatement);} base.Visit(conditionalStatement); }
// For the first assignment to a local variable in a block before a control statement is hit, // if the local variable is not mentioned previously, we turn this assignment into a local declaration. private void AddDeclarationsWithInitialValues(IEnumerable <ILocalDefinition> localVariables, BasicBlock block) { List <ILocalDefinition> topLevelLocals = new List <ILocalDefinition>(localVariables); List <ILocalDefinition> localsMet = new List <ILocalDefinition>(); for (int i = 0; i < block.Statements.Count; i++) { if (topLevelLocals.Count == 0) { break; } IExpressionStatement expressionStatement = block.Statements[i] as IExpressionStatement; if (expressionStatement != null) { IAssignment assignment = expressionStatement.Expression as IAssignment; if (assignment != null) { ILocalDefinition localDef = assignment.Target.Definition as ILocalDefinition; if (localDef != null && topLevelLocals.Contains(localDef) && !localsMet.Contains(localDef) && !this.declaredLocals.ContainsKey(localDef)) { LocalDeclarationStatement localDecl = new LocalDeclarationStatement() { LocalVariable = localDef, InitialValue = assignment.Source, Locations = new List <ILocation>(expressionStatement.Locations), }; this.declaredLocals.Add(localDef, true); block.Statements[i] = localDecl; topLevelLocals.Remove(localDef); localsMet.Add(localDef); } } } LocalFinder finder = new LocalFinder(); finder.Traverse(block.Statements[i]); foreach (ILocalDefinition local in finder.FoundLocals) { if (!localsMet.Contains(local)) { localsMet.Add(local); } } //Once we see a statement that can transfer control somewhere else, we //no longer know that any subsequent assignment dominates all references //and hence cannot postpone adding the declaration until we can unify it with the assignment. IGotoStatement gotoStatement = block.Statements[i] as IGotoStatement; if (gotoStatement != null) { break; } IConditionalStatement conditionalStatement = block.Statements[i] as IConditionalStatement; if (conditionalStatement != null) { break; } ISwitchStatement switchStatement = block.Statements[i] as ISwitchStatement; if (switchStatement != null) { break; } IForEachStatement foreachStatement = block.Statements[i] as IForEachStatement; if (foreachStatement != null) { break; } IForStatement forStatement = block.Statements[i] as IForStatement; if (forStatement != null) { break; } ITryCatchFinallyStatement tryStatement = block.Statements[i] as ITryCatchFinallyStatement; if (tryStatement != null) { break; } } }
/// <summary> /// Rewrites the given conditional statement. /// </summary> /// <param name="conditionalStatement"></param> public virtual IStatement Rewrite(IConditionalStatement conditionalStatement) { return conditionalStatement; }
/// <summary> /// Need to look for the pattern "if (!loc) then {loc = lambda;} else nop;" (or field instead of "loc") /// instead of looking for just assignments of lambdas to locals (or fields). The latter leads to the /// mis-identification of user-written code that assigns labmdas to locals (or fields). /// </summary> public override void TraverseChildren(IConditionalStatement conditionalStatement) { if (!(conditionalStatement.FalseBranch is IEmptyStatement)) goto JustTraverse; var b = conditionalStatement.TrueBranch as BlockStatement; if (b == null) goto JustTraverse; if (b.Statements.Count != 1) goto JustTraverse; var s = b.Statements[0] as IExpressionStatement; if (s == null) goto JustTraverse; var assignment = s.Expression as IAssignment; if (assignment == null) goto JustTraverse; AnonymousDelegate lambda = assignment.Source as AnonymousDelegate; if (lambda == null) goto JustTraverse; IFieldReference/*?*/ fieldReference = assignment.Target.Definition as IFieldReference; if (fieldReference != null) { if (UnspecializedMethods.IsCompilerGenerated(fieldReference) && fieldReference.Name.Value.Contains(CachedDelegateId)) { this.cachedDelegateFieldsOrLocals[fieldReference.Name.Value] = lambda; if (this.sourceMethodBody.privateHelperFieldsToRemove == null) this.sourceMethodBody.privateHelperFieldsToRemove = new Dictionary<IFieldDefinition, IFieldDefinition>(); this.sourceMethodBody.privateHelperFieldsToRemove.Add(fieldReference.ResolvedField, fieldReference.ResolvedField); } return; } ILocalDefinition/*?*/ localDefinition = assignment.Target.Definition as ILocalDefinition; if (localDefinition != null) { this.cachedDelegateFieldsOrLocals[localDefinition.Name.Value] = lambda; return; } JustTraverse: base.TraverseChildren(conditionalStatement); }
public void Visit(IConditionalStatement conditionalStatement) { this.result = this.copier.Copy(conditionalStatement); }
/// <summary> /// Generates IL for the specified conditional statement. /// </summary> /// <param name="conditionalStatement">The conditional statement.</param> public override void TraverseChildren(IConditionalStatement conditionalStatement) { this.EmitSequencePoint(conditionalStatement.Condition.Locations); ILGeneratorLabel/*?*/ endif = null; if (conditionalStatement.TrueBranch is IBreakStatement && !this.LabelIsOutsideCurrentExceptionBlock(this.currentBreakTarget)) this.VisitBranchIfTrue(conditionalStatement.Condition, this.currentBreakTarget); else if (conditionalStatement.TrueBranch is IContinueStatement && !this.LabelIsOutsideCurrentExceptionBlock(this.currentContinueTarget)) this.VisitBranchIfTrue(conditionalStatement.Condition, this.currentContinueTarget); else { ILGeneratorLabel falseCase = new ILGeneratorLabel(); this.VisitBranchIfFalse(conditionalStatement.Condition, falseCase); this.Traverse(conditionalStatement.TrueBranch); if (!this.lastStatementWasUnconditionalTransfer) { endif = new ILGeneratorLabel(); this.generator.Emit(OperationCode.Br, endif); } else { } this.generator.MarkLabel(falseCase); } this.Traverse(conditionalStatement.FalseBranch); if (endif != null) this.generator.MarkLabel(endif); this.lastStatementWasUnconditionalTransfer = false; }
public override void Visit(IConditionalStatement conditionalStatement) { //update loop nest level if (conditionalStatement.TrueBranch is IBlockStatement) { var block = (IBlockStatement)conditionalStatement.TrueBranch; var iter = block.Statements.GetEnumerator(); if (iter.MoveNext() && iter.Current is IGotoStatement) { var gotoStatement = (IGotoStatement)iter.Current; if (!_visitedGotoStatements.Contains(gotoStatement)) { _loopNestLevel--; _visitedGotoStatements.Add(gotoStatement); _loopInvariants.RemoveAt(_loopInvariants.Count - 1); //out of the outmost loop, register the instrumentation of calculated poly assignments if (_loopNestLevel == 0) { foreach (var poly in _afterLoopAssignments) { _currentInstrInfo.LoopsPolyAdd.Add(new PolyAddInformation() { Poly = poly.Item2, AddTarget = poly.Item1, AfterStatement = _currentStatement }); } _afterLoopAssignments = new List<Tuple<FieldDefinition, PolyCond>>(); foreach (var tmpInfo in _pendingOutmostLoopEndToRegister) { tmpInfo.LoopEndAt = _currentStatement; } _pendingOutmostLoopEndToRegister = null; } } } } base.Visit(conditionalStatement); }
public override void TraverseChildren(IConditionalStatement conditionalStatement) { MethodEnter(conditionalStatement); base.TraverseChildren(conditionalStatement); MethodExit(); }
/// <summary> /// Returns a deep copy of the given conditional statement. /// </summary> /// <param name="conditionalStatement"></param> public ConditionalStatement Copy(IConditionalStatement conditionalStatement) { Contract.Requires(conditionalStatement != null); Contract.Ensures(Contract.Result<ConditionalStatement>() != null); var mutableCopy = this.shallowCopier.Copy(conditionalStatement); mutableCopy.Condition = this.Copy(mutableCopy.Condition); mutableCopy.TrueBranch = this.Copy(mutableCopy.TrueBranch); mutableCopy.FalseBranch = this.Copy(mutableCopy.FalseBranch); return mutableCopy; }
private void ProcessConditionalStatement(IConditionalStatement pStatement) { if (mCurrentBlock.Terminated) mCurrentBlock = CreateBlock(CreateLabel()); HLLocation locationCondition = ProcessExpression(pStatement.Condition); HLInstructionBlock blockParent = mCurrentBlock; HLInstructionBlock blockTrueStart = CreateBlock(CreateLabel()); mCurrentBlock = blockTrueStart; ProcessStatement(pStatement.TrueBranch); HLInstructionBlock blockTrueEnd = mCurrentBlock; HLInstructionBlock blockFalseStart = CreateBlock(CreateLabel()); mCurrentBlock = blockFalseStart; ProcessStatement(pStatement.FalseBranch); HLInstructionBlock blockFalseEnd = mCurrentBlock; blockParent.EmitBranch(locationCondition, blockTrueStart.StartLabel, blockFalseStart.StartLabel); if (!blockTrueEnd.Terminated || !blockFalseEnd.Terminated) { mCurrentBlock = CreateBlock(CreateLabel()); blockTrueEnd.Terminate(mCurrentBlock.StartLabel); blockFalseEnd.Terminate(mCurrentBlock.StartLabel); } }
/// <summary> /// Returns a shallow copy of the given conditional statement. /// </summary> /// <param name="conditionalStatement"></param> public ConditionalStatement Copy(IConditionalStatement conditionalStatement) { Contract.Requires(conditionalStatement != null); Contract.Ensures(Contract.Result<ConditionalStatement>() != null); var mutable = conditionalStatement as ConditionalStatement; if (mutable != null) return mutable.Clone(); return new ConditionalStatement(conditionalStatement); }
/// <summary> /// Performs some computation with the given conditional statement. /// </summary> /// <param name="conditionalStatement"></param> public virtual void Visit(IConditionalStatement conditionalStatement) { }
/// <summary> /// Traverses the children of the conditional statement. /// </summary> public virtual void TraverseChildren(IConditionalStatement conditionalStatement) { Contract.Requires(conditionalStatement != null); this.TraverseChildren((IStatement)conditionalStatement); if (this.StopTraversal) return; this.Traverse(conditionalStatement.Condition); if (this.StopTraversal) return; this.Traverse(conditionalStatement.TrueBranch); if (this.StopTraversal) return; this.Traverse(conditionalStatement.FalseBranch); }
/// <summary> /// Performs some computation with the given conditional statement. /// </summary> /// <param name="conditionalStatement"></param> public virtual void Visit(IConditionalStatement conditionalStatement) { this.Visit((IStatement)conditionalStatement); }
/// <summary> /// /// </summary> /// <remarks>(mschaef) Works, but still a stub</remarks> /// <param name="conditionalStatement"></param> public override void TraverseChildren(IConditionalStatement conditionalStatement) { StatementTraverser thenTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext); StatementTraverser elseTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext); ExpressionTraverser condTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext); if (this.sink.Options.instrumentBranches) { var tok = conditionalStatement.Token(); thenTraverser.StmtBuilder.Add( new Bpl.AssumeCmd(tok, Bpl.Expr.True, new Bpl.QKeyValue(Bpl.Token.NoToken, "breadcrumb", new List<object> { Bpl.Expr.Literal(this.sink.UniqueNumberAcrossAllAssemblies) }, null)) ); elseTraverser.StmtBuilder.Add( new Bpl.AssumeCmd(tok, Bpl.Expr.True, new Bpl.QKeyValue(Bpl.Token.NoToken, "breadcrumb", new List<object> { Bpl.Expr.Literal(this.sink.UniqueNumberAcrossAllAssemblies) }, null)) ); } condTraverser.Traverse(conditionalStatement.Condition); thenTraverser.Traverse(conditionalStatement.TrueBranch); elseTraverser.Traverse(conditionalStatement.FalseBranch); Bpl.Expr conditionExpr = condTraverser.TranslatedExpressions.Pop(); Bpl.Type conditionType = this.sink.CciTypeToBoogie(conditionalStatement.Condition.Type); if (conditionType == this.sink.Heap.RefType) { conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Ident(this.sink.Heap.NullRef)); } else if (conditionType == Bpl.Type.Int) { conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Literal(0)); } else { System.Diagnostics.Debug.Assert(conditionType == Bpl.Type.Bool); } Bpl.IfCmd ifcmd = new Bpl.IfCmd(conditionalStatement.Token(), conditionExpr, thenTraverser.StmtBuilder.Collect(conditionalStatement.TrueBranch.Token()), null, elseTraverser.StmtBuilder.Collect(conditionalStatement.FalseBranch.Token()) ); StmtBuilder.Add(ifcmd); }
//^ ensures this.path.Count == old(this.path.Count); /// <summary> /// Traverses the given conditional statement. /// </summary> /// <param name="conditionalStatement"></param> public virtual void Visit(IConditionalStatement conditionalStatement) { if (this.stopTraversal) return; //^ int oldCount = this.path.Count; this.path.Push(conditionalStatement); this.Visit(conditionalStatement.Condition); this.Visit(conditionalStatement.TrueBranch); this.Visit(conditionalStatement.FalseBranch); //^ assume this.path.Count == oldCount+1; //True because all of the virtual methods of this class promise not decrease this.path.Count. this.path.Pop(); }
/// <summary> /// Visits the specified conditional statement. /// </summary> /// <param name="conditionalStatement">The conditional statement.</param> public override void Visit(IConditionalStatement conditionalStatement) { ConditionalStatement mutableConditionalStatement = new ConditionalStatement(conditionalStatement); this.resultStatement = this.myCodeCopier.DeepCopy(mutableConditionalStatement); }
/// <summary> /// Returns a deep copy of the given conditional statement. /// </summary> /// <param name="conditionalStatement"></param> public ConditionalStatement Copy(IConditionalStatement conditionalStatement) { var mutableCopy = this.shallowCopier.Copy(conditionalStatement); mutableCopy.Condition = this.Copy(mutableCopy.Condition); mutableCopy.TrueBranch = this.Copy(mutableCopy.TrueBranch); mutableCopy.FalseBranch = this.Copy(mutableCopy.FalseBranch); return mutableCopy; }
/// <summary> /// Returns a shallow copy of the given conditional statement. /// </summary> /// <param name="conditionalStatement"></param> public ConditionalStatement Copy(IConditionalStatement conditionalStatement) { return new ConditionalStatement(conditionalStatement); }
public override IStatement Rewrite(IConditionalStatement conditionalStatement) { var result = base.Rewrite(conditionalStatement); var mutableConditionalStatement = result as ConditionalStatement; if (mutableConditionalStatement == null) return result; var expressionPushedByTrueBranch = GetPushedExpressionFrom(conditionalStatement.TrueBranch); var expressionPushedByFalseBranch = GetPushedExpressionFrom(conditionalStatement.FalseBranch); if (expressionPushedByFalseBranch != null && expressionPushedByTrueBranch != null) { return new PushStatement() { ValueToPush = TypeInferencer.FixUpType(new Conditional() { Condition = conditionalStatement.Condition, ResultIfFalse = expressionPushedByFalseBranch, ResultIfTrue = expressionPushedByTrueBranch}), Locations = mutableConditionalStatement.Locations }; } return result; }
/// <summary> /// Generates IL for the specified conditional statement. /// </summary> /// <param name="conditionalStatement">The conditional statement.</param> public override void TraverseChildren(IConditionalStatement conditionalStatement) { this.EmitSequencePoint(conditionalStatement.Condition.Locations); ILGeneratorLabel/*?*/ endif = null; var trueBranchDelta = 0; ushort stackSizeAfterCondition = 0; if (conditionalStatement.TrueBranch is IBreakStatement && !this.LabelIsOutsideCurrentExceptionBlock(this.currentBreakTarget)) { this.VisitBranchIfTrue(conditionalStatement.Condition, this.currentBreakTarget); stackSizeAfterCondition = this.StackSize; } else if (conditionalStatement.TrueBranch is IContinueStatement && !this.LabelIsOutsideCurrentExceptionBlock(this.currentContinueTarget)) { this.VisitBranchIfTrue(conditionalStatement.Condition, this.currentContinueTarget); stackSizeAfterCondition = this.StackSize; } else { ILGeneratorLabel falseCase = new ILGeneratorLabel(); this.VisitBranchIfFalse(conditionalStatement.Condition, falseCase); stackSizeAfterCondition = this.StackSize; this.Traverse(conditionalStatement.TrueBranch); trueBranchDelta = this.StackSize - stackSizeAfterCondition; this.StackSize = stackSizeAfterCondition; if (!this.lastStatementWasUnconditionalTransfer) { endif = new ILGeneratorLabel(); this.generator.Emit(OperationCode.Br, endif); } else { } this.generator.MarkLabel(falseCase); } var beginningOfFalseBranch = this.StackSize; this.Traverse(conditionalStatement.FalseBranch); var falseBranchDelta = this.StackSize - beginningOfFalseBranch; if (trueBranchDelta != falseBranchDelta) { // // Put a breakpoint here to find (potential) bugs in the decompiler and/or this traverser's // tracking of the stack size. However, it cannot be enforced because when structured code // is not completely decompiled, the resulting explicit stack instructions cannot be tracked // accurately by this traverser. (Unstructured source code can also lead to this situation.) // // For instance, the following will result in both pushes being counted, but the stack size // should increase only by one. // // if (c) goto L1; // push e; // goto L2; // L1: // push f; // L2: // an expression containing a pop value } this.StackSize = (ushort)(stackSizeAfterCondition + Math.Max(trueBranchDelta, falseBranchDelta)); if (endif != null) { this.generator.MarkLabel(endif); this.lastStatementWasUnconditionalTransfer = false; } }
// i : loc := e0; // i+1 : if (loc) S0; else S1; // // ==> // // if (e0) S0; else S1; // // and delete statement i // // This is done only if loc is in this.branchConditionLocals // private void FindPattern(List <IStatement> statements) { for (int i = 0; i < statements.Count - 1; i++) { IExpressionStatement /*?*/ expressionStatement = statements[i] as IExpressionStatement; if (expressionStatement == null) { continue; } IAssignment /*?*/ assignmentStatement = expressionStatement.Expression as IAssignment; if (assignmentStatement == null) { continue; } if (assignmentStatement.Source is Pop) { continue; } ILocalDefinition /*?*/ localDefinition = assignmentStatement.Target.Definition as ILocalDefinition; if (localDefinition == null) { continue; } if (localDefinition.Type.TypeCode != PrimitiveTypeCode.Boolean) { continue; // cheaper test than looking in the table } if (!this.branchConditionLocals.ContainsKey(localDefinition)) { continue; } IConditionalStatement /*?*/ conditional = statements[i + 1] as IConditionalStatement; if (conditional == null) { continue; } BoundExpression /*?*/ boundExpression = conditional.Condition as BoundExpression; if (boundExpression == null) { continue; } ILocalDefinition /*?*/ localDefinition2 = boundExpression.Definition as ILocalDefinition; if (localDefinition2 == null) { continue; } if (localDefinition != localDefinition2) { continue; } var newLocs = new List <ILocation>(expressionStatement.Locations); newLocs.AddRange(conditional.Locations); statements[i + 1] = new ConditionalStatement() { Condition = assignmentStatement.Source, TrueBranch = conditional.TrueBranch, FalseBranch = conditional.FalseBranch, Locations = newLocs, }; this.sourceMethodBody.numberOfAssignments[localDefinition]--; this.sourceMethodBody.numberOfReferences[localDefinition]--; statements.RemoveAt(i); } }