Exemplo n.º 1
0
        /// <summary>
        /// Get the label for a short-circuit
        /// </summary>
        private static Label GetShortCircuitLabel(AndOrElement current, ShortCircuitInfo info, YaleIlGenerator ilg)
        {
            // We modify the given stacks so we need to clone them
            var cloneOperands  = (Stack)info.Operands.Clone();
            var cloneOperators = (Stack)info.Operators.Clone();

            // Pop all siblings
            current.PopRightChild(cloneOperands, cloneOperators);

            // Go until we run out of operators
            while (cloneOperators.Count > 0)
            {
                // Get the top operator
                var top = (AndOrElement)cloneOperators.Pop();

                // Is is a different operation?
                if (top.myOperation != current.myOperation)
                {
                    // Yes, so return a label to its right operand
                    var nextOperand = cloneOperands.Pop();
                    return(GetLabel(nextOperand, ilg, info));
                }

                // No, so keep going up the stack
                top.PopRightChild(cloneOperands, cloneOperators);
            }

            // We've reached the end of the stack so return the label for the appropriate true/false terminal
            if (current.myOperation == AndOrOperation.And)
            {
                return(GetLabel(OurFalseTerminalKey, ilg, info));
            }

            return(GetLabel(OurTrueTerminalKey, ilg, info));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Emit a short/long branch for an And/Or element
        /// </summary>
        private static OpCode GetBranchOpcode(AndOrElement op, bool longBranch)
        {
            if (op.myOperation == AndOrOperation.And)
            {
                return(longBranch ? OpCodes.Brfalse : OpCodes.Brfalse_S);
            }

            return(longBranch ? OpCodes.Brtrue : OpCodes.Brtrue_S);
        }
Exemplo n.º 3
0
        private static void EmitBranch(AndOrElement op, YaleIlGenerator ilg, Label target, ShortCircuitInfo info)
        {
            if (ilg.IsTemp)
            {
                info.Branches.AddBranch(ilg, target);

                // Temp mode; just emit a short branch and return
                var shortBranch = GetBranchOpcode(op, false);
                ilg.Emit(shortBranch, target);

                return;
            }

            // Emit the proper branch opcode

            // Determine if it is a long branch
            var longBranch = info.Branches.IsLongBranch(ilg, target);

            // Get the branch opcode
            var brOpcode = GetBranchOpcode(op, longBranch);

            // Emit the branch
            ilg.Emit(brOpcode, target);
        }