本文整理汇总了C#中Block.JoinBranch方法的典型用法代码示例。如果您正苦于以下问题:C# Block.JoinBranch方法的具体用法?C# Block.JoinBranch怎么用?C# Block.JoinBranch使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Block
的用法示例。
在下文中一共展示了Block.JoinBranch方法的7个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: VisitTry
public override void VisitTry(BoundTry node)
{
// Rules for try/catch:
// * Try stays the default;
// * Catch becomes a fork (it's only taken when an exception is
// thrown);
// * Finally is treated special. It's also executed on the default
// branch, but it's also executed from break/continue/throw/return's,
// because these flow through the finally. We don't do this here,
// but in JoinOnBlock.
var block = new Block(_branch, null, false, false, node.Finally);
PushBlock(block);
Visit(node.Try);
if (node.Catch != null)
{
// Create a block for the catch.
var catchBlock = new Block(block.Branch, null, false, false, null);
PushBlock(catchBlock);
_branch = catchBlock.Branch.Fork();
Visit(node.Catch);
catchBlock.JoinBranch(_branch);
// Create an empty fork to tell the Join algorithm that the
// Catch was an optional branch.
catchBlock.JoinBranch(catchBlock.Branch.Fork());
PopBlock(catchBlock);
}
Visit(node.Finally);
PopBlock(block);
}
示例2: VisitWhile
public override void VisitWhile(BoundWhile node)
{
// Rules for while:
// * When IsFalse(Test), we don't have any work;
// * When IsTrue(Test), _branch stays the default;
// * Otherwise, _branch becomes a fork;
// * Target for break/continue.
var result = ToBoolean(node.Test);
// If Test evaluates to a constant expression false, the while
// loop is never taken.
if (result == false)
return;
// The Test is executed on the default branch.
Visit(node.Test);
var block = new Block(_branch, FindLabel(node), true, true, null);
PushBlock(block);
_branch = block.Branch.Fork();
Visit(node.Body);
block.JoinBranch(_branch);
// Create an empty fork to tell the Join algorithm that the
// Body was an optional branch.
if (result != true)
block.JoinBranch(block.Branch.Fork());
PopBlock(block);
}
示例3: VisitSwitch
//.........这里部分代码省略.........
// Mark a read on the temporary.
MarkRead(node.Temporary);
// No cases means no work.
if (node.Cases.Count == 0)
return;
// When we only have a default case, we can just take the default.
// However, we're still a break target so we do need to create
// a block.
if (node.Cases.Count == 1 && node.Cases[0].Expression == null)
{
var block = new Block(_branch, FindLabel(node), true, false, null);
PushBlock(block);
base.VisitSwitch(node);
PopBlock(block);
return;
}
bool hadDefault = false;
// Push the block for the switch.
var switchBlock = new Block(_branch, FindLabel(node), true, false, null);
PushBlock(switchBlock);
// Clear the branch to signal the creation of a new branch.
BoundTypeManager.DefiniteAssignmentMarker.Branch caseBranch = null;
_branch = null;
for (int i = 0; i < node.Cases.Count; i++)
{
var @case = node.Cases[i];
if (@case.Expression == null)
hadDefault = true;
// Create a new branch for a series of cases (either the
// first one or on fall through).
if (caseBranch == null)
caseBranch = switchBlock.Branch.Fork();
// Create a new branch for the contents of this case.
_branch = caseBranch.Fork();
Visit(@case);
// Do we have a fall through (and we're not the last, because
// that doesn't fall through)?
if (!_branch.IsKilled && i != node.Cases.Count - 1)
{
// If we have a fall through, join the branch
// and an empty branch to close the current case.
// This makes this case optional.
caseBranch.Join(new[] { _branch, caseBranch.Fork() });
}
else
{
// If we don't have a fall through, check whether the
// branch is killed. If it isn't killed, we must be the
// last case and it's missing the break, which we insert
// here.
if (!_branch.IsKilled)
{
Debug.Assert(i == node.Cases.Count - 1);
JoinOnBlock(null, JoinType.Break);
}
// The case branch has already been joined on the switch
// block. Close this case and signal the creation of a new
// branch.
caseBranch = null;
}
}
// If we didn't have a default case, we need to create an empty
// branch for the else.
if (!hadDefault)
switchBlock.JoinBranch(switchBlock.Branch.Fork());
// And pop the switch block.
PopBlock(switchBlock);
}
示例4: VisitIf
public override void VisitIf(BoundIf node)
{
// Rules for if:
// * When IsTrue(Test), Else is not taken and Then stays the
// default branch;
// * When IsFalse(Test), Then is not taken and If stays the
// default branch;
// * Otherwise, Then and Else become a fork (even when Else
// is null).
bool? result = ToBoolean(node.Test);
// If Test evaluates to a constant that allows us to skip
// the Then, and we don't have an Else, we don't have any
// work for this node.
if (result == false && node.Else == null)
return;
// Test is executed on the default branch.
Visit(node.Test);
var block = new Block(_branch, null, false, false, null);
PushBlock(block);
if (!result.HasValue)
{
// Visit the Then.
_branch = block.Branch.Fork();
Visit(node.Then);
block.JoinBranch(_branch);
// Visit the Else. Note that we always fork the branch, even
// when we don't have an Else. The reason for this is that
// the join algorithm correctly marks variables that are
// only written to in the Then branch as not definitely
// assigned.
_branch = block.Branch.Fork();
if (node.Else != null)
Visit(node.Else);
block.JoinBranch(_branch);
}
else
{
Visit(result.Value ? node.Then : node.Else);
}
PopBlock(block);
}
示例5: VisitForEachIn
public override void VisitForEachIn(BoundForEachIn node)
{
// Rules for for each in:
// * _branch becomes a fork and we create an empty fork;
// * Target for break/continue.
// Expression is executed on the default branch.
Visit(node.Expression);
MarkWrite(node.Target);
var block = new Block(_branch, FindLabel(node), true, true, null);
PushBlock(block);
_branch = block.Branch.Fork();
Visit(node.Body);
block.JoinBranch(_branch);
// Create an empty branch to signal that the body is optional.
block.JoinBranch(block.Branch.Fork());
PopBlock(block);
}
示例6: VisitFor
public override void VisitFor(BoundFor node)
{
// Rules for for:
// * _branch stays default when IsTrue(Test); otherwise _branch
// becomes a fork;
// * Target for break/continue;
// * Increment is only executed when the default branch reaches
// the end or a continue was executed.
// Initialization and test are executed on the current branch.
Visit(node.Initialization);
Visit(node.Test);
var block = new Block(_branch, FindLabel(node), true, true, null);
_branch = block.Branch.Fork();
PushBlock(block);
Visit(node.Body);
bool wasKilled = _branch.IsKilled;
// Only visit the increment when then default branch flows there
// or a continue was executed.
if (!_branch.IsKilled || block.ContinueTaken)
{
// We need to restore the branch because if the branch is
// killed, but we have a continue, the test is still done on
// the branch.
_branch.IsKilled = false;
Visit(node.Increment);
}
if (!wasKilled)
block.JoinBranch(_branch);
// Create an extra empty branch when the test wasn't unconditional.
if (node.Test != null && ToBoolean(node.Test) != true)
block.JoinBranch(block.Branch.Fork());
PopBlock(block);
}
示例7: VisitDoWhile
public override void VisitDoWhile(BoundDoWhile node)
{
// Rules for do/while:
// * _branch stays default branch (we always take the do);
// * Target for break/continue;
// * Test is only executed when the default branch reaches the end
// or a continue was executed.
var block = new Block(_branch, FindLabel(node), true, true, null);
PushBlock(block);
_branch = block.Branch.Fork();
Visit(node.Body);
bool wasKilled = _branch.IsKilled;
if (!_branch.IsKilled || block.ContinueTaken)
{
// We need to restore the branch because if the branch is
// killed, but we have a continue, the test is still done on
// the branch.
_branch.IsKilled = false;
Visit(node.Test);
}
if (!wasKilled)
block.JoinBranch(_branch);
PopBlock(block);
}