public override void Emit(CodeGen cg) { if (_statement != null) { _statement.Emit(cg); } }
public override void Emit(CodeGen cg) { bool eoiused = false; Label eoi = cg.DefineLabel(); foreach (IfStatementTest t in _tests) { Label next = cg.DefineLabel(); if (t.Test.Span.IsValid) { cg.EmitPosition(t.Test.Start, t.Test.End); } t.Test.EmitBranchFalse(cg, next); t.Body.Emit(cg); // optimize no else case if (IsNotIfOrReturn(t.Body)) { eoiused = true; cg.Emit(OpCodes.Br, eoi); } cg.MarkLabel(next); } if (_else != null) { _else.Emit(cg); } if (eoiused) { cg.MarkLabel(eoi); } }
public override void Emit(CodeGen cg) { Slot tempContext = cg.ContextSlot; Slot newContext = cg.GetLocalTmp(typeof(CodeContext)); _scope.Emit(cg); //Locals dictionary cg.EmitCodeContext(); //CodeContext //cg.EmitBoolean(true); //Visible = true cg.EmitCall(typeof(RuntimeHelpers), "CreateNestedCodeContext"); newContext.EmitSet(cg); cg.ContextSlot = newContext; _body.Emit(cg); cg.ContextSlot = tempContext; }
public override void Emit(CodeGen cg) { Nullable <Label> firstTime = null; Label eol = cg.DefineLabel(); Label breakTarget = cg.DefineLabel(); Label continueTarget = cg.DefineLabel(); if (_increment != null) { firstTime = cg.DefineLabel(); cg.Emit(OpCodes.Br, firstTime.Value); } if (_header.IsValid) { //cg.EmitPosition(Start, _header); } cg.MarkLabel(continueTarget); if (_increment != null) { _increment.EmitAs(cg, typeof(void)); cg.MarkLabel(firstTime.Value); } if (_test != null) { _test.Emit(cg); cg.Emit(OpCodes.Brfalse, eol); } cg.PushTargets(breakTarget, continueTarget, this); _body.Emit(cg); cg.Emit(OpCodes.Br, continueTarget); cg.PopTargets(); cg.MarkLabel(eol); if (_else != null) { _else.Emit(cg); } cg.MarkLabel(breakTarget); }
public override void Emit(CodeGen cg) { if (_statement == null) { throw new InvalidOperationException("Incomplete LabelStatement"); } Label label = cg.DefineLabel(); Label label2 = cg.DefineLabel(); cg.MarkLabel(label2); cg.PushTargets(label, label2, this); _statement.Emit(cg); cg.MarkLabel(label); cg.PopTargets(); }
public override void Emit(CodeGen cg) { Label startTarget = cg.DefineLabel(); Label breakTarget = cg.DefineLabel(); Label continueTarget = cg.DefineLabel(); cg.MarkLabel(startTarget); cg.PushTargets(breakTarget, continueTarget, this); _body.Emit(cg); cg.MarkLabel(continueTarget); // TODO: Check if we need to emit position somewhere else also. //cg.EmitPosition(Start, _header); _test.Emit(cg); cg.Emit(OpCodes.Brtrue, startTarget); cg.PopTargets(); cg.MarkLabel(breakTarget); }
private void EmitGeneratorTry(CodeGen cg, TryFlowResult flow) { // // Initialize the flow control flag // Slot flowControlFlag = null; if (flow.Any) { flowControlFlag = cg.GetLocalTmp(typeof(int)); cg.EmitInt(CodeGen.FinallyExitsNormally); flowControlFlag.EmitSet(cg); } Slot exception = null; if (_finally != null) { exception = cg.GetTemporarySlot(typeof(Exception)); cg.EmitNull(); exception.EmitSet(cg); } //****************************************************************** // Entering the try block //****************************************************************** if (_target != null) { cg.MarkLabel(_target.EnsureLabel(cg)); } //****************************************************************** // If we have a 'finally', transform it into try..catch..finally // and rethrow //****************************************************************** Label endFinallyBlock = new Label(); if (_finally != null) { cg.PushExceptionBlock(TargetBlockType.Try, flowControlFlag); cg.BeginExceptionBlock(); endFinallyBlock = cg.DefineLabel(); //************************************************************** // If there is a yield in any catch, that catch will be hoisted // and we need to dispatch to it from here //************************************************************** if (_yieldInCatch) { EmitYieldDispatch(_catchYields, cg); } if (YieldInBlock(_finallyYields)) { foreach (YieldTarget yt in _finallyYields) { cg.GotoRouter.EmitGet(cg); cg.EmitInt(yt.Index); cg.Emit(OpCodes.Beq, endFinallyBlock); } } } //****************************************************************** // If we have a 'catch', start a try block to handle all the catches //****************************************************************** Label endCatchBlock = new Label(); if (HaveHandlers()) { cg.PushExceptionBlock(TargetBlockType.Try, flowControlFlag); endCatchBlock = cg.BeginExceptionBlock(); } //****************************************************************** // Emit the try block body //****************************************************************** // First, emit the dispatch within the try block EmitYieldDispatch(_tryYields, cg); // Then, emit the actual body _body.Emit(cg); //cg.EmitSequencePointNone(); //****************************************************************** // Emit the catch blocks //****************************************************************** if (HaveHandlers()) { List <CatchRecord> catches = new List <CatchRecord>(); cg.PushExceptionBlock(TargetBlockType.Catch, flowControlFlag); foreach (CatchBlock cb in _handlers) { cg.BeginCatchBlock(cb.Test); if (cb.Yield) { // The catch block body contains yield, therefore // delay the body emit till after the try block. Slot slot = cg.GetLocalTmp(cb.Test); slot.EmitSet(cg); catches.Add(new CatchRecord(slot, cb)); } else { // Save the exception (if the catch block asked for it) or pop EmitSaveExceptionOrPop(cg, cb); // Emit the body right now, since it doesn't contain yield cb.Body.Emit(cg); } } cg.PopTargets(TargetBlockType.Catch); cg.EndExceptionBlock(); cg.PopTargets(TargetBlockType.Try); //****************************************************************** // Emit the postponed catch block bodies (with yield in them) //****************************************************************** foreach (CatchRecord cr in catches) { Label next = cg.DefineLabel(); cr.Slot.EmitGet(cg); cg.EmitNull(); cg.Emit(OpCodes.Beq, next); if (cr.Block.Slot != null) { cr.Block.Slot.EmitSet(cg, cr.Slot); } cg.FreeLocalTmp(cr.Slot); cr.Block.Body.Emit(cg); cg.MarkLabel(next); //cg.EmitSequencePointNone(); } } //****************************************************************** // Emit the finally body //****************************************************************** if (_finally != null) { cg.MarkLabel(endFinallyBlock); cg.PushExceptionBlock(TargetBlockType.Catch, flowControlFlag); cg.BeginCatchBlock(typeof(Exception)); exception.EmitSet(cg); cg.PopTargets(TargetBlockType.Catch); cg.PushExceptionBlock(TargetBlockType.Finally, flowControlFlag); cg.BeginFinallyBlock(); Label noExit = cg.DefineLabel(); cg.GotoRouter.EmitGet(cg); cg.EmitInt(CodeGen.GotoRouterYielding); cg.Emit(OpCodes.Bne_Un_S, noExit); cg.Emit(OpCodes.Endfinally); cg.MarkLabel(noExit); EmitYieldDispatch(_finallyYields, cg); // Emit the finally body _finally.Emit(cg); // Rethrow the exception, if any Label noThrow = cg.DefineLabel(); exception.EmitGet(cg); cg.EmitNull(); cg.Emit(OpCodes.Beq, noThrow); exception.EmitGet(cg); cg.Emit(OpCodes.Throw); cg.MarkLabel(noThrow); cg.FreeLocalTmp(exception); cg.EndExceptionBlock(); cg.PopTargets(TargetBlockType.Finally); cg.PopTargets(TargetBlockType.Try); // // Emit the flow control for finally, if there was any. // EmitFinallyFlowControl(cg, flow, flowControlFlag); //cg.EmitSequencePointNone(); } // Clear the target labels ClearLabels(_tryYields); ClearLabels(_catchYields); if (_target != null) { _target.Clear(); } }