Beispiel #1
0
 // Emit a short/long branch for an And/Or element
 private static OpCode GetBranchOpcode(AndOrElement op, bool longBranch)
 {
     if (op.MyOperation == AndOrOperation.And)
     {
         if (longBranch == true)
         {
             return OpCodes.Brfalse;
         }
         else
         {
             return OpCodes.Brfalse_S;
         }
     }
     else
     {
         if (longBranch == true)
         {
             return OpCodes.Brtrue;
         }
         else
         {
             return OpCodes.Brtrue_S;
         }
     }
 }
Beispiel #2
0
    // Get the label for a short-circuit
    private static Label GetShortCircuitLabel(AndOrElement current, ShortCircuitInfo info, FleeILGenerator ilg)
    {
        // We modify the given stacks so we need to clone them
        Stack cloneOperands = (Stack)info.Operands.Clone();
        Stack 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
            AndOrElement top = (AndOrElement)cloneOperators.Pop();

            // Is is a different operation?
            if (top.MyOperation != current.MyOperation)
            {
                // Yes, so return a label to its right operand
                object nextOperand = cloneOperands.Pop();
                return GetLabel(nextOperand, ilg, info);
            }
            else
            {
                // 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);
        }
        else
        {
            return GetLabel(OurTrueTerminalKey, ilg, info);
        }
    }
Beispiel #3
0
    private static void EmitBranch(AndOrElement op, FleeILGenerator ilg, Label target, ShortCircuitInfo info)
    {
        if (ilg.IsTemp == true)
        {
            info.Branches.AddBranch(ilg, target);

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

            return;
        }

        // Emit the proper branch opcode

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

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

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