コード例 #1
0
        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);
        }
コード例 #2
0
        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);
            }
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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();
        }
コード例 #5
0
        //!!! 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();
        }