public override void Emit(CodeGen cg) { Label eol = cg.DefineLabel(); Label breakTarget = cg.DefineLabel(); Label continueTarget = cg.DefineLabel(); cg.MarkLabel(continueTarget); cg.EmitPosition(start, header); cg.EmitTestTrue(test); cg.Emit(OpCodes.Brfalse, eol); cg.PushTargets(breakTarget, continueTarget); body.Emit(cg); cg.Emit(OpCodes.Br, continueTarget); cg.PopTargets(); cg.MarkLabel(eol); if (elseStmt != null) { elseStmt.Emit(cg); } cg.MarkLabel(breakTarget); }
public override void Emit(CodeGen cg) { Label eol = cg.DefineLabel(); Label breakTarget = cg.DefineLabel(); Label continueTarget = cg.DefineLabel(); cg.EmitPosition(start, header); list.Emit(cg); cg.EmitCall(typeof(Ops), "GetEnumerator"); Slot iter; if (cg.IsGenerator()) { iter = cg.Names.GetTempSlot("iter", typeof(IEnumerator)); } else { iter = cg.GetLocalTmp(typeof(IEnumerator)); } iter.EmitSet(cg); cg.MarkLabel(continueTarget); iter.EmitGet(cg); cg.EmitCall(typeof(IEnumerator), "MoveNext"); cg.Emit(OpCodes.Brfalse, eol); cg.PushTargets(breakTarget, continueTarget); iter.EmitGet(cg); cg.EmitCall(typeof(IEnumerator).GetProperty("Current").GetGetMethod()); lhs.EmitSet(cg); body.Emit(cg); cg.Emit(OpCodes.Br, continueTarget); cg.PopTargets(); cg.MarkLabel(eol); if (elseStmt != null) { elseStmt.Emit(cg); } cg.MarkLabel(breakTarget); if (cg.IsGenerator()) { //!!! need to free my temp } else { cg.FreeLocalTmp(iter); } }
public override void Emit(CodeGen cg) { Label eoi = cg.DefineLabel(); foreach (IfStmtTest t in tests) { Label next = cg.DefineLabel(); cg.EmitPosition(t.start, t.header); cg.EmitTestTrue(t.test); cg.Emit(OpCodes.Brfalse, next); t.body.Emit(cg); // optimize no else case cg.Emit(OpCodes.Br, eoi); cg.MarkLabel(next); } if (elseStmt != null) { elseStmt.Emit(cg); } cg.MarkLabel(eoi); }
public override void Emit(CodeGen cg) { cg.EmitPosition(start, header); Slot choiceVar = null; Slot returnVar = null; Label endOfTry = new Label(); if (yieldTargets.Count > 0) { Label startOfBlock = cg.DefineLabel(); choiceVar = cg.GetLocalTmp(typeof(int)); returnVar = cg.GetLocalTmp(typeof(bool)); cg.EmitInt(0); returnVar.EmitSet(cg); cg.EmitInt(-1); choiceVar.EmitSet(cg); cg.Emit(OpCodes.Br, startOfBlock); int index = 0; foreach (YieldTarget yt in yieldTargets) { cg.MarkLabel(yt.topBranchTarget); cg.EmitInt(index++); choiceVar.EmitSet(cg); cg.Emit(OpCodes.Br, startOfBlock); } cg.MarkLabel(startOfBlock); } cg.PushTryBlock(); cg.BeginExceptionBlock(); if (yieldTargets.Count > 0) { int index = 0; endOfTry = cg.DefineLabel(); foreach (YieldTarget yt in yieldTargets) { choiceVar.EmitGet(cg); cg.EmitInt(index++); cg.Emit(OpCodes.Beq, endOfTry); } } body.Emit(cg); if (yieldTargets.Count > 0) { cg.MarkLabel(endOfTry); } cg.PopTargets(); cg.PushFinallyBlock(returnVar); cg.BeginFinallyBlock(); if (yieldTargets.Count > 0) { int index = 0; foreach (YieldTarget yt in yieldTargets) { choiceVar.EmitGet(cg); cg.EmitInt(index++); cg.Emit(OpCodes.Beq, yt.tryBranchTarget); } } finallyStmt.Emit(cg); cg.EndExceptionBlock(); cg.PopTargets(); if (yieldTargets.Count > 0) { Label noReturn = cg.DefineLabel(); returnVar.EmitGet(cg); cg.Emit(OpCodes.Brfalse_S, noReturn); cg.Emit(OpCodes.Ldc_I4_1); cg.EmitReturn(); cg.MarkLabel(noReturn); } yieldTargets.Clear(); }
//!!! need to evaluate break/continue through a try block public override void Emit(CodeGen cg) { Slot choiceVar = null; cg.EmitPosition(start, header); if (yieldTargets.Count > 0) { Label startOfBlock = cg.DefineLabel(); choiceVar = cg.GetLocalTmp(typeof(int)); cg.EmitInt(-1); choiceVar.EmitSet(cg); cg.Emit(OpCodes.Br, startOfBlock); int index = 0; foreach (YieldTarget yt in yieldTargets) { cg.MarkLabel(yt.topBranchTarget); cg.EmitInt(index++); choiceVar.EmitSet(cg); cg.Emit(OpCodes.Br, startOfBlock); } cg.MarkLabel(startOfBlock); } Label afterCatch = new Label(); Label afterElse = cg.DefineLabel(); cg.PushTryBlock(); cg.BeginExceptionBlock(); if (yieldTargets.Count > 0) { int index = 0; foreach (YieldTarget yt in yieldTargets) { choiceVar.EmitGet(cg); cg.EmitInt(index); cg.Emit(OpCodes.Beq, yt.tryBranchTarget); index++; } cg.FreeLocalTmp(choiceVar); } body.Emit(cg); if (yieldInExcept) { afterCatch = cg.DefineLabel(); cg.Emit(OpCodes.Leave, afterCatch); } cg.BeginCatchBlock(typeof(Exception)); // Extract state from the carrier exception cg.EmitCallerContext(); cg.EmitCall(typeof(Ops), "ExtractException"); Slot pyExc = cg.GetLocalTmp(typeof(object)); Slot tmpExc = cg.GetLocalTmp(typeof(object)); pyExc.EmitSet(cg); if (yieldInExcept) { cg.EndExceptionBlock(); cg.PopTargets(); } foreach (TryStmtHandler handler in handlers) { cg.EmitPosition(handler.start, handler.header); Label next = cg.DefineLabel(); if (handler.test != null) { pyExc.EmitGet(cg); handler.test.Emit(cg); cg.EmitCall(typeof(Ops), "CheckException"); if (handler.target != null) { tmpExc.EmitSet(cg); tmpExc.EmitGet(cg); } cg.EmitPythonNone(); cg.Emit(OpCodes.Ceq); cg.Emit(OpCodes.Brtrue, next); } if (handler.target != null) { tmpExc.EmitGet(cg); handler.target.EmitSet(cg); } cg.PushExceptionBlock(Targets.TargetBlockType.Catch, null); handler.body.Emit(cg); cg.EmitCallerContext(); cg.EmitCall(typeof(Ops), "ClearException"); cg.PopTargets(); if (yieldInExcept) { cg.Emit(OpCodes.Br, afterElse); } else { cg.Emit(OpCodes.Leave, afterElse); } cg.MarkLabel(next); } cg.FreeLocalTmp(tmpExc); if (yieldInExcept) { pyExc.EmitGet(cg); cg.Emit(OpCodes.Throw); cg.MarkLabel(afterCatch); } else { cg.Emit(OpCodes.Rethrow); cg.EndExceptionBlock(); cg.PopTargets(); } if (elseStmt != null) { elseStmt.Emit(cg); } cg.MarkLabel(afterElse); cg.FreeLocalTmp(pyExc); yieldTargets.Clear(); }