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

ClrCompare() private method

For QilExpression types that map directly to CLR primitive types, the built-in CLR comparison operators can be used to perform the specified relational operation.
private ClrCompare ( QilNodeType relOp, XmlTypeCode code ) : void
relOp QilNodeType
code XmlTypeCode
return void
        private void ClrCompare(QilNodeType relOp, XmlTypeCode code) {
            OpCode opcode;
            Label lblTrue;

            switch (this.iterCurr.CurrentBranchingContext) {
                case BranchingContext.OnFalse:
                    // Reverse the comparison operator
                    // Use Bxx_Un OpCodes to handle NaN case for double and single types
                    if (code == XmlTypeCode.Double || code == XmlTypeCode.Float) {
                        switch (relOp) {
                            case QilNodeType.Gt: opcode = OpCodes.Ble_Un; break;
                            case QilNodeType.Ge: opcode = OpCodes.Blt_Un; break;
                            case QilNodeType.Lt: opcode = OpCodes.Bge_Un; break;
                            case QilNodeType.Le: opcode = OpCodes.Bgt_Un; break;
                            case QilNodeType.Eq: opcode = OpCodes.Bne_Un; break;
                            case QilNodeType.Ne: opcode = OpCodes.Beq; break;
                            default: Debug.Assert(false); opcode = OpCodes.Nop; break;
                        }
                    }
                    else {
                        switch (relOp)
                        {
                            case QilNodeType.Gt: opcode = OpCodes.Ble; break;
                            case QilNodeType.Ge: opcode = OpCodes.Blt; break;
                            case QilNodeType.Lt: opcode = OpCodes.Bge; break;
                            case QilNodeType.Le: opcode = OpCodes.Bgt; break;
                            case QilNodeType.Eq: opcode = OpCodes.Bne_Un; break;
                            case QilNodeType.Ne: opcode = OpCodes.Beq; break;
                            default: Debug.Assert(false); opcode = OpCodes.Nop; break;
                        }
                    }
                    this.helper.Emit(opcode, this.iterCurr.LabelBranch);
                    this.iterCurr.Storage = StorageDescriptor.None();
                    break;

                case BranchingContext.OnTrue:
                    switch (relOp) {
                        case QilNodeType.Gt: opcode = OpCodes.Bgt; break;
                        case QilNodeType.Ge: opcode = OpCodes.Bge; break;
                        case QilNodeType.Lt: opcode = OpCodes.Blt; break;
                        case QilNodeType.Le: opcode = OpCodes.Ble; break;
                        case QilNodeType.Eq: opcode = OpCodes.Beq; break;
                        case QilNodeType.Ne: opcode = OpCodes.Bne_Un; break;
                        default: Debug.Assert(false); opcode = OpCodes.Nop; break;
                    }
                    this.helper.Emit(opcode, this.iterCurr.LabelBranch);
                    this.iterCurr.Storage = StorageDescriptor.None();
                    break;

                default:
                    Debug.Assert(this.iterCurr.CurrentBranchingContext == BranchingContext.None);
                    switch (relOp) {
                        case QilNodeType.Gt: this.helper.Emit(OpCodes.Cgt); break;
                        case QilNodeType.Lt: this.helper.Emit(OpCodes.Clt); break;
                        case QilNodeType.Eq: this.helper.Emit(OpCodes.Ceq); break;
                        default:
                            switch (relOp) {
                                case QilNodeType.Ge: opcode = OpCodes.Bge_S; break;
                                case QilNodeType.Le: opcode = OpCodes.Ble_S; break;
                                case QilNodeType.Ne: opcode = OpCodes.Bne_Un_S; break;
                                default: Debug.Assert(false); opcode = OpCodes.Nop; break;
                            }

                            // Push "true" if comparison succeeds, "false" otherwise
                            lblTrue = this.helper.DefineLabel();
                            this.helper.Emit(opcode, lblTrue);
                            this.helper.ConvBranchToBool(lblTrue, true);
                            break;
                    }
                    this.iterCurr.Storage = StorageDescriptor.Stack(typeof(bool), false);
                    break;
            }
        }
XmlILVisitor