private void EmitConditional(FleeILGenerator ilg, IServiceProvider services, BranchManager bm) { Label falseLabel = bm.FindLabel("falseLabel"); Label 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); }
private void EmitListIn(FleeILGenerator ilg, IServiceProvider services, BranchManager bm) { CompareElement ce = new CompareElement(); Label endLabel = bm.FindLabel("endLabel"); Label trueTerminal = bm.FindLabel("trueTerminal"); // Cache the operand since we will be comparing against it a lot LocalBuilder lb = ilg.DeclareLocal(MyOperand.ResultType); int targetIndex = lb.LocalIndex; MyOperand.Emit(ilg, services); Utility.EmitStoreLocal(ilg, targetIndex); // Wrap our operand in a local shim LocalBasedElement targetShim = new LocalBasedElement(MyOperand, targetIndex); // Emit the compares foreach (ExpressionElement 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); }
public override void Emit(FleeILGenerator ilg, IServiceProvider services) { if ((MyTargetCollectionType != null)) { this.EmitCollectionIn(ilg, services); } else { BranchManager bm = new BranchManager(); bm.GetLabel("endLabel", ilg); bm.GetLabel("trueTerminal", ilg); // Do a fake emit to get branch positions FleeILGenerator ilgTemp = this.CreateTempFleeILGenerator(ilg); Utility.SyncFleeILGeneratorLabels(ilg, ilgTemp); this.EmitListIn(ilgTemp, services, bm); bm.ComputeBranches(); // Do the real emit this.EmitListIn(ilg, services, bm); } }
private static void EmitBranchToTrueTerminal(FleeILGenerator ilg, Label trueTerminal, BranchManager bm) { if (ilg.IsTemp == true) { bm.AddBranch(ilg, trueTerminal); ilg.Emit(OpCodes.Brtrue_S, trueTerminal); } else if (bm.IsLongBranch(ilg, trueTerminal) == false) { ilg.Emit(OpCodes.Brtrue_S, trueTerminal); } else { ilg.Emit(OpCodes.Brtrue, trueTerminal); } }
public ShortCircuitInfo() { this.Operands = new Stack(); this.Operators = new Stack(); this.Branches = new BranchManager(); }