示例#1
0
        private void EmitConditional(FleeILGenerator ilg, IServiceProvider services)
        {
            Label falseLabel = ilg.DefineLabel();
            Label endLabel   = ilg.DefineLabel();

            // Emit the condition
            _myCondition.Emit(ilg, services);

            // On false go to the false operand
            ilg.EmitBranchFalse(falseLabel);

            // Emit the true operand
            _myWhenTrue.Emit(ilg, services);
            ImplicitConverter.EmitImplicitConvert(_myWhenTrue.ResultType, _myResultType, ilg);

            // Jump to end
            ilg.EmitBranch(endLabel);

            ilg.MarkLabel(falseLabel);

            // Emit the false operand
            _myWhenFalse.Emit(ilg, services);
            ImplicitConverter.EmitImplicitConvert(_myWhenFalse.ResultType, _myResultType, ilg);
            // Fall through to end
            ilg.MarkLabel(endLabel);
        }
示例#2
0
        /// <summary>
        /// Emit a short-circuited logical operation sequence
        /// The idea: Store all the leaf operands in a stack with the leftmost at the top and rightmost at the bottom.
        /// For each operand, emit it and try to find an end point for when it short-circuits.  This means we go up through
        /// the stack of operators (ignoring siblings) until we find a different operation (then emit a branch to its right operand)
        /// or we reach the root (emit a branch to a true/false).
        /// Repeat the process for all operands and then emit the true/false/last operand end cases.
        /// </summary>
        /// <param name="ilg"></param>
        /// <param name="info"></param>
        /// <param name="services"></param>
        private void EmitLogical(FleeILGenerator ilg, ShortCircuitInfo info, IServiceProvider services)
        {
            // We always have an end label
            Label endLabel = ilg.DefineLabel();

            // Populate our data structures
            this.PopulateData(info);

            // Emit the sequence
            EmitLogicalShortCircuit(ilg, info, services);

            // Get the last operand
            ExpressionElement terminalOperand = (ExpressionElement)info.Operands.Pop();

            // Emit it
            EmitOperand(terminalOperand, info, ilg, services);

            // only 1-3 opcodes, always a short branch
            ilg.EmitBranch(endLabel);

            // Emit our true/false terminals
            EmitTerminals(info, ilg, endLabel);

            // Mark the end
            ilg.MarkLabel(endLabel);
        }