Пример #1
0
        protected void VisitAsyncTryCatchStatement() {
            TryCatchStatement tryCatchStatement = this.TryCatchStatement;

            this.Emitter.AsyncBlock.Steps.Last().JumpToStep = this.Emitter.AsyncBlock.Step;

            var tryStep = this.Emitter.AsyncBlock.AddAsyncStep();
            AsyncTryInfo tryInfo = new AsyncTryInfo();
            tryInfo.StartStep = tryStep.Step;

            this.Emitter.IgnoreBlock = tryCatchStatement.TryBlock;
            tryCatchStatement.TryBlock.AcceptVisitor(this.Emitter);
            tryStep = this.Emitter.AsyncBlock.Steps.Last();
            tryInfo.EndStep = tryStep.Step;

            List<IAsyncStep> catchSteps = new List<IAsyncStep>();

            foreach(var clause in tryCatchStatement.CatchClauses) {
                var catchStep = this.Emitter.AsyncBlock.AddAsyncStep();
                catchSteps.Add(catchStep);

                this.PushLocals();
                var varName = clause.VariableName;

                if(!String.IsNullOrEmpty(varName) && !this.Emitter.Locals.ContainsKey(varName)) {
                    varName = this.AddLocal(varName, clause.Type);
                }

                tryInfo.CatchBlocks.Add(new Tuple<string, string, int>(varName, clause.Type.IsNull ? "Bridge.Exception" : BridgeTypes.ToJsName(clause.Type, this.Emitter), catchStep.Step));

                this.Emitter.IgnoreBlock = clause.Body;
                clause.Body.AcceptVisitor(this.Emitter);
                this.PopLocals();
                this.WriteNewLine();
            }

            if(/*tryCatchStatement.CatchClauses.Count == 0 && */!this.Emitter.Locals.ContainsKey("$e")) {
                this.AddLocal("$e", AstType.Null);
            }

            IAsyncStep finalyStep = null;
            if(!tryCatchStatement.FinallyBlock.IsNull) {
                finalyStep = this.Emitter.AsyncBlock.AddAsyncStep(tryCatchStatement.FinallyBlock);
                this.Emitter.IgnoreBlock = tryCatchStatement.FinallyBlock;
                tryCatchStatement.FinallyBlock.AcceptVisitor(this.Emitter);

                var finallyNode = this.GetParentFinallyBlock(tryCatchStatement, false);

                this.WriteNewLine();

                this.WriteIf();
                this.WriteOpenParentheses();
                this.Write("$jumpFromFinally > -1");
                this.WriteCloseParentheses();
                this.WriteSpace();
                this.BeginBlock();
                if(finallyNode != null) {
                    var hashcode = finallyNode.GetHashCode();
                    this.Emitter.AsyncBlock.JumpLabels.Add(new AsyncJumpLabel {
                        Node = finallyNode,
                        Output = this.Emitter.Output
                    });
                    this.Write("$step = ${" + hashcode + "};");
                    this.WriteNewLine();
                    this.Write("continue;");
                }
                else {
                    this.Write("$step = $jumpFromFinally;");
                    this.WriteNewLine();
                    this.Write("$jumpFromFinally = null;");
                }

                this.WriteNewLine();
                this.EndBlock();

                this.WriteSpace();
                this.WriteElse();
                this.WriteIf();
                this.WriteOpenParentheses();
                this.Write("$e");
                this.WriteCloseParentheses();
                this.WriteSpace();
                this.BeginBlock();
                this.Write("$returnTask.setError($e);");
                this.WriteNewLine();
                this.WriteReturn(false);
                this.WriteSemiColon();
                this.WriteNewLine();
                this.EndBlock();

                this.WriteSpace();
                this.WriteElse();
                this.WriteIf();
                this.WriteOpenParentheses();
                this.Write("Bridge.isDefined($returnValue)");
                this.WriteCloseParentheses();
                this.WriteSpace();
                this.BeginBlock();

                if(finallyNode != null) {
                    var hashcode = finallyNode.GetHashCode();
                    this.Emitter.AsyncBlock.JumpLabels.Add(new AsyncJumpLabel {
                        Node = finallyNode,
                        Output = this.Emitter.Output
                    });
                    this.Write("$step = ${" + hashcode + "};");
                    this.WriteNewLine();
                    this.Write("continue;");
                }
                else {
                    this.Write("$returnTask.setResult($returnValue);");
                    this.WriteNewLine();
                    this.WriteReturn(false);
                    this.WriteSemiColon();
                }

                this.WriteNewLine();
                this.EndBlock();

                if(!this.Emitter.Locals.ContainsKey("$e")) {
                    this.AddLocal("$e", AstType.Null);
                }
            }

            var nextStep = this.Emitter.AsyncBlock.AddAsyncStep();
            if(finalyStep != null) {
                tryInfo.FinallyStep = finalyStep.Step;
            }

            if(finalyStep != null) {
                finalyStep.JumpToStep = nextStep.Step;
            }

            tryStep.JumpToStep = finalyStep != null ? finalyStep.Step : nextStep.Step;

            foreach(var step in catchSteps) {
                step.JumpToStep = finalyStep != null ? finalyStep.Step : nextStep.Step;
            }

            this.Emitter.AsyncBlock.TryInfos.Add(tryInfo);
        }
Пример #2
0
        protected void VisitAsyncTryCatchStatement()
        {
            TryCatchStatement tryCatchStatement = this.TryCatchStatement;

            this.Emitter.AsyncBlock.Steps.Last().JumpToStep = this.Emitter.AsyncBlock.Step;

            var          tryStep = this.Emitter.AsyncBlock.AddAsyncStep();
            AsyncTryInfo tryInfo = new AsyncTryInfo();

            tryInfo.StartStep = tryStep.Step;

            this.Emitter.IgnoreBlock = tryCatchStatement.TryBlock;
            tryCatchStatement.TryBlock.AcceptVisitor(this.Emitter);
            tryStep         = this.Emitter.AsyncBlock.Steps.Last();
            tryInfo.EndStep = tryStep.Step;

            List <IAsyncStep> catchSteps = new List <IAsyncStep>();

            foreach (var clause in tryCatchStatement.CatchClauses)
            {
                var catchStep = this.Emitter.AsyncBlock.AddAsyncStep();
                catchSteps.Add(catchStep);

                this.PushLocals();
                var varName = clause.VariableName;

                if (!String.IsNullOrEmpty(varName) && !this.Emitter.Locals.ContainsKey(varName))
                {
                    varName = this.AddLocal(varName, clause.Type);
                }

                tryInfo.CatchBlocks.Add(new Tuple <string, string, int>(varName, clause.Type.IsNull ? "Bridge.Exception" : BridgeTypes.ToJsName(clause.Type, this.Emitter), catchStep.Step));

                this.Emitter.IgnoreBlock = clause.Body;
                clause.Body.AcceptVisitor(this.Emitter);
                this.PopLocals();
                this.WriteNewLine();
            }

            if (/*tryCatchStatement.CatchClauses.Count == 0 && */ !this.Emitter.Locals.ContainsKey("$e"))
            {
                this.AddLocal("$e", AstType.Null);
            }

            IAsyncStep finalyStep = null;

            if (!tryCatchStatement.FinallyBlock.IsNull)
            {
                finalyStep = this.Emitter.AsyncBlock.AddAsyncStep(tryCatchStatement.FinallyBlock);
                this.Emitter.IgnoreBlock = tryCatchStatement.FinallyBlock;
                tryCatchStatement.FinallyBlock.AcceptVisitor(this.Emitter);

                var finallyNode = this.GetParentFinallyBlock(tryCatchStatement, false);

                this.WriteNewLine();

                this.WriteIf();
                this.WriteOpenParentheses();
                this.Write("$jumpFromFinally > -1");
                this.WriteCloseParentheses();
                this.WriteSpace();
                this.BeginBlock();
                if (finallyNode != null)
                {
                    var hashcode = finallyNode.GetHashCode();
                    this.Emitter.AsyncBlock.JumpLabels.Add(new AsyncJumpLabel {
                        Node   = finallyNode,
                        Output = this.Emitter.Output
                    });
                    this.Write("$step = ${" + hashcode + "};");
                    this.WriteNewLine();
                    this.Write("continue;");
                }
                else
                {
                    this.Write("$step = $jumpFromFinally;");
                    this.WriteNewLine();
                    this.Write("$jumpFromFinally = null;");
                }

                this.WriteNewLine();
                this.EndBlock();

                this.WriteSpace();
                this.WriteElse();
                this.WriteIf();
                this.WriteOpenParentheses();
                this.Write("$e");
                this.WriteCloseParentheses();
                this.WriteSpace();
                this.BeginBlock();
                this.Write("$returnTask.setError($e);");
                this.WriteNewLine();
                this.WriteReturn(false);
                this.WriteSemiColon();
                this.WriteNewLine();
                this.EndBlock();

                this.WriteSpace();
                this.WriteElse();
                this.WriteIf();
                this.WriteOpenParentheses();
                this.Write("Bridge.isDefined($returnValue)");
                this.WriteCloseParentheses();
                this.WriteSpace();
                this.BeginBlock();

                if (finallyNode != null)
                {
                    var hashcode = finallyNode.GetHashCode();
                    this.Emitter.AsyncBlock.JumpLabels.Add(new AsyncJumpLabel {
                        Node   = finallyNode,
                        Output = this.Emitter.Output
                    });
                    this.Write("$step = ${" + hashcode + "};");
                    this.WriteNewLine();
                    this.Write("continue;");
                }
                else
                {
                    this.Write("$returnTask.setResult($returnValue);");
                    this.WriteNewLine();
                    this.WriteReturn(false);
                    this.WriteSemiColon();
                }

                this.WriteNewLine();
                this.EndBlock();

                if (!this.Emitter.Locals.ContainsKey("$e"))
                {
                    this.AddLocal("$e", AstType.Null);
                }
            }

            var nextStep = this.Emitter.AsyncBlock.AddAsyncStep();

            if (finalyStep != null)
            {
                tryInfo.FinallyStep = finalyStep.Step;
            }

            if (finalyStep != null)
            {
                finalyStep.JumpToStep = nextStep.Step;
            }

            tryStep.JumpToStep = finalyStep != null ? finalyStep.Step : nextStep.Step;

            foreach (var step in catchSteps)
            {
                step.JumpToStep = finalyStep != null ? finalyStep.Step : nextStep.Step;
            }

            this.Emitter.AsyncBlock.TryInfos.Add(tryInfo);
        }