public override void GenerateMSIL(ILGenerator ilGenerator, TypeBuilder typeBuilder) { Condition.GenerateMSIL(ilGenerator, typeBuilder); ilGenerator.Emit(OpCodes.Ldc_I4_0); ilGenerator.Emit(OpCodes.Ceq); if (ElsePart == null) { Label labelAfterIf = ilGenerator.DefineLabel(); ilGenerator.Emit(OpCodes.Brtrue, labelAfterIf); ThenPart.GenerateMSIL(ilGenerator, typeBuilder); ilGenerator.MarkLabel(labelAfterIf); } else { Label labelForFalse = ilGenerator.DefineLabel(); Label labelAfterIf = ilGenerator.DefineLabel(); ilGenerator.Emit(OpCodes.Brtrue, labelForFalse); ThenPart.GenerateMSIL(ilGenerator, typeBuilder); ilGenerator.Emit(OpCodes.Br_S, labelAfterIf); ilGenerator.MarkLabel(labelForFalse); ElsePart.GenerateMSIL(ilGenerator, typeBuilder); ilGenerator.MarkLabel(labelAfterIf); } }
public override bool HasExternalLibraryCall() { if (ElsePart != null) { return(Condition.HasExternalLibraryCall() || ThenPart.HasExternalLibraryCall() || ElsePart.HasExternalLibraryCall()); } else { return(Condition.HasExternalLibraryCall() || ThenPart.HasExternalLibraryCall()); } }
public override Expression ClearConstant(Dictionary <string, Expression> constMapping) { return(new If(Condition.ClearConstant(constMapping), ThenPart.ClearConstant(constMapping), ElsePart == null ? null : ElsePart.ClearConstant(constMapping))); }
protected override void GenerateCode(CodeGenContext context) { var target = ThenPart.GetBranchTarget(); if (target.HasValue) { // // Normally, we evaluate // if ( a ) { b = 1; } // such that if "a" evaluates to false, then we branch around the then-part // and if "a" evaluates to true, we fall-thru to the then-part // But when the then-part is itself a goto statement of some sort: // if ( a ) { goto L; } // if ( a ) { break; } // if ( a ) { continue; } // Then instead of branching around a branch instruction, // we reverse the evaluation condition and supply the control flow target: // so that if "a" evaluates to true, then we branch (goto/break/continue), // and if "a" evaluates to false, we don't branch // context.SetPrettyPrintProlog("If-Goto\t"); Condition.GenerateCodeForConditionalBranchWithPrettyPrint(context, target.Value, true); Dump.WriteLine("<then part branch incorporated into preceding condition>"); context.SetPrettyPrintProlog("ElsePart\t"); ElsePart?.GenerateCodeWithPrettyPrint(context); } else if (ElsePart == null) { context.SetPrettyPrintProlog("Condition\t"); var joinPoint = context.CreateLabel(); Condition.GenerateCodeForConditionalBranchWithPrettyPrint(context, joinPoint, false); context.SetPrettyPrintProlog("ThenPart"); ThenPart.GenerateCodeWithPrettyPrint(context); context.InsertComment("if-then rejoin"); context.PlaceLabelHere(joinPoint); } /* else if ( ElsePart.IsBranchStatement () { }*/ else { var elsePartLabel = context.CreateLabel(); context.SetPrettyPrintProlog("Condition\t"); Condition.GenerateCodeForConditionalBranchWithPrettyPrint(context, elsePartLabel, false); context.SetPrettyPrintProlog("ThenPart\t"); ThenPart.GenerateCodeWithPrettyPrint(context); var joinPoint = context.CreateLabel(); context.InsertComment("end of ThenPart"); context.GenerateUnconditionalBranch(joinPoint); context.SetPrettyPrintProlog("ElsePart\t"); context.PlaceLabelHere(elsePartLabel); context.InsertComment("start of ElsePart"); ElsePart.GenerateCodeWithPrettyPrint(context); context.InsertComment("if-then-else rejoin"); context.PlaceLabelHere(joinPoint); } }