Esempio n. 1
0
        protected void EmitGeneratorBody()
        {
            BeginBlock();

            var asyncTryVisitor = new AsyncTryVisitor();

            Node.AcceptChildren(asyncTryVisitor);
            var needTry = true;

            Emitter.AsyncVariables.Add(JS.Vars.ASYNC_JUMP);
            if (needTry)
            {
                Emitter.AsyncVariables.Add(JS.Vars.ASYNC_RETURN_VALUE);

                WriteTry();
                BeginBlock();
            }

            WriteFor();
            Write("(;;) ");
            BeginBlock();

            WriteSwitch();
            Write("(" + JS.Vars.ASYNC_STEP + ") ");
            BeginBlock();

            Step = 0;
            var writer = SaveWriter();

            AddAsyncStep();

            Body.AcceptVisitor(Emitter);

            RestoreWriter(writer);

            InjectSteps();

            WriteNewLine();
            EndBlock();

            WriteNewLine();
            EndBlock();

            if (needTry)
            {
                if (!Emitter.Locals.ContainsKey(JS.Vars.ASYNC_E))
                {
                    AddLocal(JS.Vars.ASYNC_E, null, AstType.Null);
                }

                WriteNewLine();
                EndBlock();
                Write(" catch(" + JS.Vars.ASYNC_E1 + ") ");
                BeginBlock();
                Write(JS.Vars.ASYNC_E + " = " + JS.Types.System.Exception.CREATE + "(" + JS.Vars.ASYNC_E1 + ");");
                WriteNewLine();
                InjectCatchHandlers();

                WriteNewLine();
                EndBlock();
            }

            WriteNewLine();
            EndBlock();
        }
Esempio n. 2
0
        protected void EmitAsyncBody()
        {
            BeginBlock();

            var asyncTryVisitor = new AsyncTryVisitor();

            Node.AcceptChildren(asyncTryVisitor);
            var needTry = asyncTryVisitor.Found || IsTaskReturn;

            Emitter.AsyncVariables.Add(JS.Vars.ASYNC_JUMP);
            if (needTry)
            {
                if (IsTaskReturn)
                {
                    Emitter.AsyncVariables.Add(JS.Vars.ASYNC_TCS + " = new " + JS.Types.TASK_COMPLETION_SOURCE + "()");
                }

                Emitter.AsyncVariables.Add(JS.Vars.ASYNC_RETURN_VALUE);

                Write("try");
                WriteSpace();
                BeginBlock();
            }

            Write("for (;;) ");
            BeginBlock();
            WriteIndent();
            int checkerPos = Emitter.Output.Length;

            WriteNewLine();
            Write("switch (" + JS.Vars.ASYNC_STEP + ") ");

            BeginBlock();

            Step = 0;
            var writer = SaveWriter();

            AddAsyncStep();

            if (Body.Parent is LambdaExpression && Body is Expression && IsTaskReturn && ReturnType.FullName == "System.Threading.Tasks.Task" && ReturnType.TypeParameterCount > 0)
            {
                new ReturnBlock(Emitter, (Expression)Body).Emit();
            }
            else
            {
                var level = Emitter.InitialLevel;
                ((Emitter)Emitter).InitialLevel = 0;
                Emitter.ResetLevel();
                Body.AcceptVisitor(Emitter);
                ((Emitter)Emitter).InitialLevel = level;
            }

            RestoreWriter(writer);

            InjectSteps();

            WriteNewLine();
            EndBlock();

            InjectStepsChecker(checkerPos);
            WriteNewLine();
            EndBlock();

            if (needTry)
            {
                if (!Emitter.Locals.ContainsKey(JS.Vars.ASYNC_E))
                {
                    AddLocal(JS.Vars.ASYNC_E, null, AstType.Null);
                }

                WriteNewLine();
                EndBlock();
                Write(" catch(" + JS.Vars.ASYNC_E1 + ") ");
                BeginBlock();
                Write(JS.Vars.ASYNC_E + " = " + JS.Types.System.Exception.CREATE + "(" + JS.Vars.ASYNC_E1 + ");");
                WriteNewLine();
                InjectCatchHandlers();

                WriteNewLine();
                EndBlock();
            }

            WriteNewLine();
            EndBlock();
        }