public override void GenerateCode(Emit.MethodBodyGenerator generator) { // Generate code for the start of the statement. var statementLocals = new StatementLocals() { NonDefaultBreakStatementBehavior = true, NonDefaultSourceSpanBehavior = true }; GenerateStartOfStatement(generator, statementLocals); // Set up some labels. var continueTarget = generator.CreateLabel(); var breakTarget = generator.CreateLabel(); // Emit the initialization statement. if (Initialization != null) { Initialization.GenerateCode(generator); } // The inner loop starts here. var startOfLoop = generator.CreateLabel(); var startOfCondition = generator.CreateLabel(); if (CheckConditionAtEnd == false) { generator.Branch(startOfCondition); } //start of loop generator.DefineLabelPosition(startOfLoop); // Emit the loop body. generator.PushBreakOrContinueInfo(Labels, breakTarget, continueTarget, false); Body.GenerateCode(generator); generator.PopBreakOrContinueInfo(); // The continue statement jumps here. generator.DefineLabelPosition(continueTarget); // Increment the loop variable. if (Increments != null) { Increments.ForEach(e => e.Accept(generator).GenerateCode(generator)); } generator.DefineLabelPosition(startOfCondition); // Check the condition and jump to the end if it is false. if (Condition != null) { // generator.MarkSequencePoint(ConditionStatement.Span); Condition.Accept(generator).GenerateCode(generator); generator.CallStatic(Utils.ReflectionHelpers.BoooleanToBool); generator.BranchIfTrue(startOfLoop); } // Define the end of the loop (actually just after). generator.DefineLabelPosition(breakTarget); // Generate code for the end of the statement. GenerateEndOfStatement(generator, statementLocals); }
/// <inheritdoc/> public override void GenerateCode(Emit.MethodBodyGenerator generator) { // Generate code for the start of the statement. var statementLocals = new StatementLocals(); GenerateStartOfStatement(generator, statementLocals); var condition = Condition.Accept(generator); // Generate code for condition convert to System.Boolean condition.GenerateCode(generator, Emit.MethodCompileOption.Return); if (condition.Type != typeof(bool)) { if (condition.Type == TypeProvider.BooleanType) { generator.CallStatic(Utils.ReflectionHelpers.BoooleanToBool); } else if (condition.Type.TryImplicitConvert(TypeProvider.BooleanType, out MethodInfo op_Implicit)) { generator.CallStatic(op_Implicit); generator.CallStatic(Utils.ReflectionHelpers.BoooleanToBool); } else { throw new System.InvalidCastException($"Unable to cast object of type {condition.Type} to {TypeProvider.BooleanType}"); } } // We will need a label at the end of the if statement. var endOfEverything = generator.CreateLabel(); if (Else == null) { //jump to end of if clause generator.BranchIfFalse(endOfEverything); //generate code for then clause Then.GenerateCode(generator); } else { //branch to else clause if false var startOfElseClause = generator.CreateLabel(); generator.BranchIfFalse(startOfElseClause); //generate code for then clause Then.GenerateCode(generator); //brach to end of everything generator.Branch(endOfEverything); //generate code of else clause generator.DefineLabelPosition(startOfElseClause); Else.GenerateCode(generator); } //define label at end of statement generator.DefineLabelPosition(endOfEverything); //generate code for end of statement GenerateEndOfStatement(generator, statementLocals); }
public override void GenerateCode(Emit.MethodBodyGenerator generator, Emit.MethodCompileOption option) { Left.GenerateCode(generator); generator.Duplicate(); var end = generator.CreateLabel(); if (Left.Type.IsValueType) { if (Left.Type.TryImplicitConvert(TypeProvider.BooleanType, out System.Reflection.MethodInfo op_Implicit)) { generator.CallStatic(op_Implicit); generator.CallStatic(Utils.ReflectionHelpers.BoooleanToBool); } else { throw new System.InvalidCastException($"Unable to cast object of type {Left.Type} to {TypeProvider.BooleanType}"); } } generator.BranchIfTrue(end); generator.Pop(); Right.GenerateCode(generator, Emit.MethodCompileOption.Dupplicate); generator.DefineLabelPosition(end); }