public override Statement VisitBranch(Branch branch) { if(branch == null) return null; if(branch.Target == null) return null; branch.Condition = this.VisitExpression(branch.Condition); int n = this.localsStack.top + 1; LocalsStack targetStack = (LocalsStack)this.StackLocalsAtEntry[branch.Target.UniqueKey]; if(targetStack == null) { this.StackLocalsAtEntry[branch.Target.UniqueKey] = this.localsStack.Clone(); return branch; } // Target block has an entry stack that is different from the current stack. Need to copy stack // before branching. if(n <= 0) return branch; //Empty stack, no need to copy StatementList statements = new StatementList(); this.localsStack.Transfer(targetStack, statements); statements.Add(branch); return new Block(statements); }
public override void VisitBranch(Branch branch) { if (branch == null || branch.Target == null) return; if (branch.Target == branchTargetToReplace) { branch.Target = this.newBranchTarget; return; } base.VisitBranch(branch); }
//public override Block VisitBlock(Block block) { // if(block.Statements != null && block.Statements.Count == 1) { // Return r = block.Statements[0] as Return; // if(r != null) { // Statement s = this.VisitReturn(r); // Block retBlock = s as Block; // if(retBlock != null) { // block.Statements = retBlock.Statements; // return block; // } else { // return base.VisitBlock(block); // } // } else { // return base.VisitBlock(block); // } // } else { // return base.VisitBlock(block); // } //} public override Statement VisitReturn(Return Return) { if (Return == null) { return null; } returnCount++; this.lastReturnSourceContext = Return.SourceContext; StatementList stmts = new StatementList(); Return.Expression = this.VisitExpression(Return.Expression); if (Return.Expression != null) { MethodCall mc = Return.Expression as MethodCall; if (mc != null && mc.IsTailCall) { mc.IsTailCall = false; } var assgnmt = new AssignmentStatement(result, Return.Expression); assgnmt.SourceContext = Return.SourceContext; stmts.Add(assgnmt); } // the branch is a "leave" out of the try block that the body will be // in. var branch = new Branch(null, newExit, false, false, this.leaveExceptionBody); branch.SourceContext = Return.SourceContext; stmts.Add(branch); return new Block(stmts); }
private static Statement WrapTryCatch(Method method, Statement statement) { Block afterCatches = new Block(new StatementList()); Block tryBlock = new Block(new StatementList()); Block blockAfterTryBody = new Block(null); tryBlock.Statements.Add(statement); tryBlock.Statements.Add(new Branch(null, afterCatches, false, true, true)); tryBlock.Statements.Add(blockAfterTryBody); Block catchBlock = new Block(new StatementList()); // emit code that pops the exception and fools fxcop Block branchTargetToFoolFxCop = new Block(null); var branch = new Branch(new Expression(NodeType.Pop), branchTargetToFoolFxCop); SourceContext hiddenContext = new SourceContext(HiddenDocument.Document); branch.SourceContext = hiddenContext; catchBlock.Statements.Add(branch); var rethrowStatement = new Throw(); rethrowStatement.SourceContext = hiddenContext; rethrowStatement.NodeType = NodeType.Rethrow; catchBlock.Statements.Add(rethrowStatement); catchBlock.Statements.Add(branchTargetToFoolFxCop); var leave = new Branch(null, afterCatches, false, true, true); leave.SourceContext = hiddenContext; catchBlock.Statements.Add(leave); Block tryCatch = new Block(new StatementList()); tryCatch.Statements.Add(tryBlock); tryCatch.Statements.Add(catchBlock); tryCatch.Statements.Add(afterCatches); if (method.ExceptionHandlers == null) method.ExceptionHandlers = new ExceptionHandlerList(); ExceptionHandler exHandler = new ExceptionHandler(); exHandler.TryStartBlock = tryBlock; exHandler.BlockAfterTryEnd = blockAfterTryBody; exHandler.HandlerStartBlock = catchBlock; exHandler.BlockAfterHandlerEnd = afterCatches; exHandler.FilterType = SystemTypes.Exception; exHandler.HandlerType = NodeType.Catch; method.ExceptionHandlers.Add(exHandler); return tryCatch; }
private void EmitRecursionGuardAroundChecks(Method method, Block newBody, StatementList checks) { StatementList stmts = new StatementList(); Block preconditionsStart = new Block(stmts); Block finallyStart = null; Block finallyEnd = new Block(); // branch target for skipping the checks // test if we are an auto property and need to disable the check if we are in construction if (this.ReentrancyFlag != null && (method.IsPropertyGetter || method.IsPropertySetter) && HelperMethods.IsAutoPropertyMember(method) && !method.IsStatic) { newBody.Statements.Add(new Branch(new MemberBinding(method.ThisParameter, this.ReentrancyFlag), finallyEnd)); } // don't add try finally if there are no precondition or if the method is a constructor (peverify issue) if (NeedsRecursionGuard(method, checks)) { // emit recursion check finallyStart = new Block(new StatementList()); // if (insideContractEvaluation > $recursionGuard$) goto finallyEnd // try { // insideContractEvaluation++; // checks; // leave; // } finally { // insideContractEvaluation--; // } // // SPECIAL CASE for auto properties where we made invariants into pre/post, we need to avoid the check if we are // evaluating the invariant. // // if (this.$evaluatingInvariant || insideContractEvaluation > $recursionGuard$) goto finallyEnd // newBody.Statements.Add(new Branch(new BinaryExpression(new MemberBinding(null, this.runtimeContracts.InContractEvaluationField), new Literal(this.runtimeContracts.RecursionGuardCountFor(method), SystemTypes.Int32), NodeType.Gt), finallyEnd)); stmts.Add(new AssignmentStatement(new MemberBinding(null, this.runtimeContracts.InContractEvaluationField), new BinaryExpression(new MemberBinding(null, this.runtimeContracts.InContractEvaluationField), Literal.Int32One, NodeType.Add))); stmts.Add(new Block(checks)); var leave = new Branch(); leave.Target = finallyEnd; leave.LeavesExceptionBlock = true; stmts.Add(leave); finallyStart.Statements.Add(new AssignmentStatement(new MemberBinding(null, this.runtimeContracts.InContractEvaluationField), new BinaryExpression(new MemberBinding(null, this.runtimeContracts.InContractEvaluationField), Literal.Int32One, NodeType.Sub))); finallyStart.Statements.Add(new EndFinally()); } else { stmts.Add(new Block(checks)); } newBody.Statements.Add(preconditionsStart); if (finallyStart != null) { newBody.Statements.Add(finallyStart); var finallyHandler = new ExceptionHandler(); finallyHandler.TryStartBlock = preconditionsStart; finallyHandler.BlockAfterTryEnd = finallyStart; finallyHandler.HandlerStartBlock = finallyStart; finallyHandler.BlockAfterHandlerEnd = finallyEnd; finallyHandler.HandlerType = NodeType.Finally; method.ExceptionHandlers.Add(finallyHandler); } // branch target for skipping the checks newBody.Statements.Add(finallyEnd); }
public override void VisitBranch(Branch branch) { branch.ShortOffset = false; }
public override Statement VisitBranch(Branch branch) { if (branch == null) return null; branch = (Branch)base.VisitBranch((Branch)branch.Clone()); if (branch == null) return null; branch.Target = this.VisitBlock(branch.Target); return branch; }
public override Statement VisitBranch(Branch branch) { throw new NotImplementedException("Node type not yet supported"); }
public override Statement VisitBranch(Branch branch) { branch = (Branch)branch.Clone(); // remember this statement on the list to adjust branches this.branchInstructions.Add(branch); if (branch.Condition == null) return branch; if (this.performConstantFoldingOnBranchConditions) { Literal l = AsConstant(branch.Condition); if (l != null) { if (Equals(l.Value, true) || Equals(l.Value, 1)) { branch.Condition = null; return branch; } if (Equals(l.Value, false) || Equals(l.Value, 0)) { return null; } } } branch.Condition = simplify(branch.Condition); return branch; }
public SpecialBranch (Branch oldBranch, Block target) : base(null, target) { this.LeavesExceptionBlock = oldBranch.LeavesExceptionBlock; this.SourceContext = oldBranch.SourceContext; }
// The "leave" instruction block.Statements[i] is replaced with a branch instruction // to a ChainBlocks of duplicated finally blocks (which are now normal blocks) that finally // arrives in the original branch target. private void ProcessLeave (Block block, int i, Branch leave) { Debug.Assert(block != null); Debug.Assert(block.Statements[i] is Branch && ((Branch)block.Statements[i]).LeavesExceptionBlock); //Console.Out.WriteLine("process leave from " + CodePrinter.b2s(block) + "," + i); Block originalLeaveTarget = ((Branch) block.Statements[i]).Target; // 1. find the list of all finally blocks "traversed" by the branch IEnumerable/*<ExceptionHandler>*/ list_finally = GetFinallyHandlersForLeave(block, i); // 2. duplicate and ChainBlocks them with jumps between them Block modBlock = block; int modIndex = i; // the modIndex'th instruction of modBlock will be replaced with a "chaining" Branch bool isFirstHandler = true; Block firstBlockInFinally, lastBlockInFinally; foreach(ExceptionHandler eh in list_finally) { DuplicateFinallyBody(eh, block, out firstBlockInFinally, out lastBlockInFinally); Debug.Assert(firstBlockInFinally != null && lastBlockInFinally != null); ChainBlocks(modBlock, modIndex, firstBlockInFinally, isFirstHandler); isFirstHandler = false; modBlock = lastBlockInFinally; } ChainBlocks(modBlock, modIndex, originalLeaveTarget, isFirstHandler); #if DEBUGxxx Console.WriteLine(); Console.WriteLine("-------------------------------------------------------------"); Console.WriteLine(); SimpleDisplay(Console.Out, this.method); Console.WriteLine("NEW:"); foreach (Block b in new_blocks) { SimpleDisplay(Console.Out, b, null); } #endif }
public override Statement VisitBranch(Branch branch) { if (branch == null) return null; return ((Branch)branch.Clone()); }
public override Statement VisitBranch(Branch branch) { // update the branch target for non-leave branches if ( ! branch.LeavesExceptionBlock || branch is SpecialBranch) { branch.Target = get_new_target(branch.Target); } return branch; }
public override Statement VisitBranch(Branch branch) { if (branch == null) return null; if (branch.Condition != null) throw new InvalidOperationException("Unexpected branch condition in BBSplitter"); // Check to see if a basic block has been created for this target yet BasicBlock bbTarget = (BasicBlock)branchTargets[branch.Target.UniqueKey]; // If not, create one now and register it in branchTargets if (bbTarget == null) { bbTarget = new BasicBlock(null); AddBlock(bbTarget); bbTarget.SourceContext = branch.SourceContext; bbTarget.MiddleOfTransition = true; branchTargets[branch.Target.UniqueKey] = bbTarget; } #if false // Note: this optimization was overly aggressive because it assumes that branch targets // fall within the current atomic block. If not, then we need an extra "branch" block // which can be the end of the atomic block. if (this.insideAtomicBlock) { // We don't need a basic block for the branch itself. We just redirect the // CurrentContinuation to the target of the branch. CurrentContinuation = bbTarget; } else #endif { // If we aren't in an atomic block, we can't optimize away the block for the // goto itself. BasicBlock branchBlock = new BasicBlock(null, bbTarget); AddBlock(branchBlock); branchBlock.SourceContext = branch.SourceContext; CurrentContinuation = branchBlock; // Remember this branch if it happens to be inside an atomic block. If the // target is *not* within the atomic block, then we'll need to do some // fixup work later. if (this.insideAtomicBlock) atomicBranches.Add(branchBlock); } return branch; }
public virtual Statement VisitBranch(Branch branch) { if (branch == null) return null; branch.Condition = this.VisitExpression(branch.Condition); return branch; }
public override Statement VisitBranch(Branch branch) { if (branch == null) return null; if (branch.Target == null) return null; this.VisitBlock(branch.Target); this.lastBranchWasUnconditional = branch.Condition == null; return branch; }
public override Statement VisitBranch(Branch branch) { Debug.Assert(false, "Unexpected Branch node in Normalizer"); return null; }
public EventingVisitor(Action<Branch> visitBranch) { VisitedBranch += visitBranch; } public event Action<Branch> VisitedBranch; public override Statement VisitBranch(Branch branch) { if (VisitedBranch != null) VisitedBranch(branch); return base.VisitBranch(branch); }