コード例 #1
0
ファイル: In.cs プロジェクト: netgrim/FleeSharp
		private void EmitListIn(FleeILGenerator ilg, IServiceProvider services, BranchManager bm)
		{
			var ce = new CompareElement();
			var endLabel = bm.FindLabel("endLabel");
			var trueTerminal = bm.FindLabel("trueTerminal");

			// Cache the operand since we will be comparing against it a lot
			var lb = ilg.DeclareLocal(MyOperand.ResultType);
			int targetIndex = lb.LocalIndex;

			MyOperand.Emit(ilg, services);
			Utility.EmitStoreLocal(ilg, targetIndex);

			// Wrap our operand in a local shim
			var targetShim = new LocalBasedElement(MyOperand, targetIndex);

			// Emit the compares
			foreach (var argumentElement in MyArguments) {
				ce.Initialize(targetShim, argumentElement, LogicalCompareOperation.Equal);
				ce.Emit(ilg, services);

				EmitBranchToTrueTerminal(ilg, trueTerminal, bm);
			}

			ilg.Emit(OpCodes.Ldc_I4_0);
			ilg.Emit(OpCodes.Br_S, endLabel);

			bm.MarkLabel(ilg, trueTerminal);
			ilg.MarkLabel(trueTerminal);

			ilg.Emit(OpCodes.Ldc_I4_1);

			bm.MarkLabel(ilg, endLabel);
			ilg.MarkLabel(endLabel);
		}
コード例 #2
0
ファイル: AndOr.cs プロジェクト: netgrim/FleeSharp
    // Emit the end cases for a short-circuit
    private static void EmitTerminals(ShortCircuitInfo info, FleeILGenerator ilg, Label endLabel)
    {
        // Emit the false case if it was used
        if (info.Branches.HasLabel(OurFalseTerminalKey) == true)
        {
            Label falseLabel = info.Branches.FindLabel(OurFalseTerminalKey);

            // Mark the label and note its position
            ilg.MarkLabel(falseLabel);
            MarkBranchTarget(info, falseLabel, ilg);

            ilg.Emit(OpCodes.Ldc_I4_0);

            // If we also have a true terminal, then skip over it
            if (info.Branches.HasLabel(OurTrueTerminalKey) == true)
            {
                ilg.Emit(OpCodes.Br_S, endLabel);
            }
        }

        // Emit the true case if it was used
        if (info.Branches.HasLabel(OurTrueTerminalKey) == true)
        {
            Label trueLabel = info.Branches.FindLabel(OurTrueTerminalKey);

            // Mark the label and note its position
            ilg.MarkLabel(trueLabel);
            MarkBranchTarget(info, trueLabel, ilg);

            ilg.Emit(OpCodes.Ldc_I4_1);
        }
    }
コード例 #3
0
ファイル: AndOr.cs プロジェクト: netgrim/FleeSharp
    // 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.
    private void EmitLogical(FleeILGenerator ilg, ShortCircuitInfo info, IServiceProvider services)
    {
        // We always have an end label
        info.Branches.GetLabel(OurEndLabelKey, ilg);

        // 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);
        // And jump to the end
        Label endLabel = info.Branches.FindLabel(OurEndLabelKey);
        ilg.Emit(OpCodes.Br_S, endLabel);

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

        // Mark the end
        ilg.MarkLabel(endLabel);
    }
コード例 #4
0
ファイル: AndOr.cs プロジェクト: netgrim/FleeSharp
    private static void EmitOperand(ExpressionElement operand, ShortCircuitInfo info, FleeILGenerator ilg, IServiceProvider services)
    {
        // Is this operand the target of a label?
        if (info.Branches.HasLabel(operand) == true)
        {
            // Yes, so mark it
            Label leftLabel = info.Branches.FindLabel(operand);
            ilg.MarkLabel(leftLabel);

            // Note the label's position
            MarkBranchTarget(info, leftLabel, ilg);
        }

        // Emit the operand
        operand.Emit(ilg, services);
    }
コード例 #5
0
ファイル: Conditional.cs プロジェクト: netgrim/FleeSharp
		private void EmitConditional(FleeILGenerator ilg, IServiceProvider services, BranchManager bm)
		{
			var falseLabel = bm.FindLabel("falseLabel");
			var endLabel = bm.FindLabel("endLabel");

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

			// On false go to the false operand
			if (ilg.IsTemp == true) {
				bm.AddBranch(ilg, falseLabel);
				ilg.Emit(OpCodes.Brfalse_S, falseLabel);
			} else if (bm.IsLongBranch(ilg, falseLabel) == false) {
				ilg.Emit(OpCodes.Brfalse_S, falseLabel);
			} else {
				ilg.Emit(OpCodes.Brfalse, falseLabel);
			}

			// Emit the true operand
			MyWhenTrue.Emit(ilg, services);
			ImplicitConverter.EmitImplicitConvert(MyWhenTrue.ResultType, MyResultType, ilg);

			// Jump to end
			if (ilg.IsTemp == true) {
				bm.AddBranch(ilg, endLabel);
				ilg.Emit(OpCodes.Br_S, endLabel);
			} else if (bm.IsLongBranch(ilg, endLabel) == false) {
				ilg.Emit(OpCodes.Br_S, endLabel);
			} else {
				ilg.Emit(OpCodes.Br, endLabel);
			}

			bm.MarkLabel(ilg, falseLabel);
			ilg.MarkLabel(falseLabel);

			// Emit the false operand
			MyWhenFalse.Emit(ilg, services);
			ImplicitConverter.EmitImplicitConvert(MyWhenFalse.ResultType, MyResultType, ilg);
			// Fall through to end
			bm.MarkLabel(ilg, endLabel);
			ilg.MarkLabel(endLabel);
		}