System.Xml.Xsl.IlGen.XmlILVisitor.VisitOr C# (CSharp) Method

VisitOr() protected method

Generate code for QilNodeType.Or.
BranchingContext.OnFalse context: (expr1) or (expr2) ==> if (expr1) goto LabelTemp; if (!expr2) goto LabelParent; LabelTemp: BranchingContext.OnTrue context: (expr1) or (expr2) ==> if (expr1) goto LabelParent; if (expr1) goto LabelParent; BranchingContext.None context: (expr1) or (expr2) ==> if (expr1) goto LabelTemp; if (expr1) goto LabelTemp; push false(); goto LabelSkip; LabelTemp: push true(); LabelSkip:
protected VisitOr ( QilBinary ndOr ) : QilNode
ndOr QilBinary
return QilNode
        protected override QilNode VisitOr(QilBinary ndOr) {
            Label lblTemp = new Label();

            // Visit left branch
            switch (this.iterCurr.CurrentBranchingContext) {
                case BranchingContext.OnFalse:
                    // If left condition evaluates to true, jump to new label that will be fixed
                    // just beyond the second condition
                    lblTemp = this.helper.DefineLabel();
                    NestedVisitWithBranch(ndOr.Left, BranchingContext.OnTrue, lblTemp);
                    break;

                case BranchingContext.OnTrue:
                    // If left condition evaluates to true, branch to true label
                    NestedVisitWithBranch(ndOr.Left, BranchingContext.OnTrue, this.iterCurr.LabelBranch);
                    break;

                default:
                    // If left condition evalutes to true, jump to code that pushes "true"
                    Debug.Assert(this.iterCurr.CurrentBranchingContext == BranchingContext.None);
                    lblTemp = this.helper.DefineLabel();
                    NestedVisitWithBranch(ndOr.Left, BranchingContext.OnTrue, lblTemp);
                    break;
            }

            // Visit right branch
            switch (this.iterCurr.CurrentBranchingContext) {
                case BranchingContext.OnFalse:
                    // If right condition evaluates to false, branch to false label
                    NestedVisitWithBranch(ndOr.Right, BranchingContext.OnFalse, this.iterCurr.LabelBranch);
                    break;

                case BranchingContext.OnTrue:
                    // If right condition evaluates to true, branch to true label
                    NestedVisitWithBranch(ndOr.Right, BranchingContext.OnTrue, this.iterCurr.LabelBranch);
                    break;

                default:
                    // If right condition evalutes to true, jump to code that pushes "true".
                    // Otherwise, if both conditions evaluate to false, fall through code path
                    // will push "false".
                    NestedVisitWithBranch(ndOr.Right, BranchingContext.OnTrue, lblTemp);
                    break;
            }

            switch (this.iterCurr.CurrentBranchingContext) {
                case BranchingContext.OnFalse:
                    // Anchor true label
                    this.helper.MarkLabel(lblTemp);
                    goto case BranchingContext.OnTrue;

                case BranchingContext.OnTrue:
                    this.iterCurr.Storage = StorageDescriptor.None();
                    break;

                case BranchingContext.None:
                    // Convert branch targets into push of true/false
                    this.helper.ConvBranchToBool(lblTemp, true);
                    this.iterCurr.Storage = StorageDescriptor.Stack(typeof(bool), false);
                    break;
            }

            return ndOr;
        }
XmlILVisitor