예제 #1
0
        private static void EmitTerminals(ShortCircuitInfo info, FleeIlGenerator ilg, Label endLabel)
        {
            var flag = info.Branches.HasLabel(RuntimeHelpers.GetObjectValue(ourFalseTerminalKey));

            if (flag)
            {
                var falseLabel = info.Branches.FindLabel(RuntimeHelpers.GetObjectValue(ourFalseTerminalKey));
                ilg.MarkLabel(falseLabel);
                MarkBranchTarget(info, falseLabel, ilg);
                ilg.Emit(OpCodes.Ldc_I4_0);
                var flag2 = info.Branches.HasLabel(RuntimeHelpers.GetObjectValue(ourTrueTerminalKey));
                if (flag2)
                {
                    ilg.Emit(OpCodes.Br_S, endLabel);
                }
            }
            var flag3 = info.Branches.HasLabel(RuntimeHelpers.GetObjectValue(ourTrueTerminalKey));

            if (flag3)
            {
                var trueLabel = info.Branches.FindLabel(RuntimeHelpers.GetObjectValue(ourTrueTerminalKey));
                ilg.MarkLabel(trueLabel);
                MarkBranchTarget(info, trueLabel, ilg);
                ilg.Emit(OpCodes.Ldc_I4_1);
            }
        }
예제 #2
0
        private void PopulateData(ShortCircuitInfo info)
        {
            var andOrChild = this.myRightChild as AndOrElement;
            var flag       = andOrChild == null;

            if (flag)
            {
                info.Operands.Push(this.myRightChild);
            }
            else
            {
                andOrChild.PopulateData(info);
            }
            info.Operators.Push(this);
            andOrChild = this.myLeftChild as AndOrElement;
            var flag2 = andOrChild == null;

            if (flag2)
            {
                info.Operands.Push(this.myLeftChild);
            }
            else
            {
                andOrChild.PopulateData(info);
            }
        }
예제 #3
0
        private static Label GetShortCircuitLabel(AndOrElement current, ShortCircuitInfo info, FleeIlGenerator ilg)
        {
            var cloneOperands  = (Stack)info.Operands.Clone();
            var cloneOperators = (Stack)info.Operators.Clone();

            current.PopRightChild(cloneOperands, cloneOperators);
            Label getShortCircuitLabel;

            while (cloneOperators.Count > 0)
            {
                var top  = (AndOrElement)cloneOperators.Pop();
                var flag = top.myOperation != current.myOperation;
                if (flag)
                {
                    var nextOperand = RuntimeHelpers.GetObjectValue(cloneOperands.Pop());
                    getShortCircuitLabel = GetLabel(RuntimeHelpers.GetObjectValue(nextOperand), ilg, info);
                    return(getShortCircuitLabel);
                }
                top.PopRightChild(cloneOperands, cloneOperators);
            }
            var flag2 = current.myOperation == AndOrOperation.And;

            if (flag2)
            {
                getShortCircuitLabel = GetLabel(RuntimeHelpers.GetObjectValue(ourFalseTerminalKey), ilg, info);
                return(getShortCircuitLabel);
            }
            getShortCircuitLabel = GetLabel(RuntimeHelpers.GetObjectValue(ourTrueTerminalKey), ilg, info);
            return(getShortCircuitLabel);
        }
예제 #4
0
        private static void MarkBranchTarget(ShortCircuitInfo info, Label target, FleeIlGenerator ilg)
        {
            var isTemp = ilg.IsTemp;

            if (isTemp)
            {
                info.Branches.MarkLabel(ilg, target);
            }
        }
예제 #5
0
 private static void EmitLogicalShortCircuit(FleeIlGenerator ilg, ShortCircuitInfo info, IServiceProvider services)
 {
     while (info.Operators.Count != 0)
     {
         var op          = (AndOrElement)info.Operators.Pop();
         var leftOperand = (ExpressionElement)info.Operands.Pop();
         EmitOperand(leftOperand, info, ilg, services);
         var i = GetShortCircuitLabel(op, info, ilg);
         EmitBranch(op, ilg, i, info);
     }
 }
예제 #6
0
        private void DoEmitLogical(FleeIlGenerator ilg, IServiceProvider services)
        {
            var info    = new ShortCircuitInfo();
            var ilgTemp = this.CreateTempFleeIlGenerator(ilg);

            Utility.SyncFleeILGeneratorLabels(ilg, ilgTemp);
            this.EmitLogical(ilgTemp, info, services);
            info.ClearTempState();
            info.Branches.ComputeBranches();
            Utility.SyncFleeILGeneratorLabels(ilgTemp, ilg);
            this.EmitLogical(ilg, info, services);
        }
예제 #7
0
        private static void EmitOperand(ExpressionElement operand, ShortCircuitInfo info, FleeIlGenerator ilg,
                                        IServiceProvider services)
        {
            var flag = info.Branches.HasLabel(operand);

            if (flag)
            {
                var leftLabel = info.Branches.FindLabel(operand);
                ilg.MarkLabel(leftLabel);
                MarkBranchTarget(info, leftLabel, ilg);
            }
            operand.Emit(ilg, services);
        }
예제 #8
0
        private void EmitLogical(FleeIlGenerator ilg, ShortCircuitInfo info, IServiceProvider services)
        {
            info.Branches.GetLabel(RuntimeHelpers.GetObjectValue(ourEndLabelKey), ilg);
            this.PopulateData(info);
            EmitLogicalShortCircuit(ilg, info, services);
            var terminalOperand = (ExpressionElement)info.Operands.Pop();

            EmitOperand(terminalOperand, info, ilg, services);
            var endLabel = info.Branches.FindLabel(RuntimeHelpers.GetObjectValue(ourEndLabelKey));

            ilg.Emit(OpCodes.Br_S, endLabel);
            EmitTerminals(info, ilg, endLabel);
            ilg.MarkLabel(endLabel);
        }
예제 #9
0
 private static Label GetLabel(object key, FleeIlGenerator ilg, ShortCircuitInfo info)
 {
     return(info.Branches.GetLabel(RuntimeHelpers.GetObjectValue(key), ilg));
 }
예제 #10
0
        private static void EmitBranch(AndOrElement op, FleeIlGenerator ilg, Label target, ShortCircuitInfo info)
        {
            var isTemp = ilg.IsTemp;

            if (isTemp)
            {
                info.Branches.AddBranch(ilg, target);
                var shortBranch = GetBranchOpcode(op, false);
                ilg.Emit(shortBranch, target);
            }
            else
            {
                var longBranch = info.Branches.IsLongBranch(ilg, target);
                var brOpcode   = GetBranchOpcode(op, longBranch);
                ilg.Emit(brOpcode, target);
            }
        }