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 (!this.Emitter.Locals.ContainsKey("$async_e")) { this.AddLocal("$async_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("$async_e"); this.WriteCloseParentheses(); this.WriteSpace(); this.BeginBlock(); this.Write("$tcs.setException($async_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("$tcs.setResult($returnValue);"); this.WriteNewLine(); this.WriteReturn(false); this.WriteSemiColon(); } this.WriteNewLine(); this.EndBlock(); if (!this.Emitter.Locals.ContainsKey("$async_e")) { this.AddLocal("$async_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); }
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)) { varName = "$e"; } if (!this.Emitter.Locals.ContainsKey(varName)) { varName = this.AddLocal(varName, clause.Type); } tryInfo.CatchBlocks.Add(new Tuple <string, string, int>(varName, Helpers.TranslateTypeReference(clause.Type, this.Emitter), catchStep.Step)); this.Emitter.IgnoreBlock = clause.Body; clause.Body.AcceptVisitor(this.Emitter); this.PopLocals(); } 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(); this.Emitter.IgnoreBlock = tryCatchStatement.FinallyBlock; tryCatchStatement.FinallyBlock.AcceptVisitor(this.Emitter); if (catchSteps.Count == 0) { this.WriteNewLine(); this.Write("throw $e;"); 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); }
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); }
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(); this.PushLocals(); var varName = clause.VariableName; if (!String.IsNullOrEmpty(varName) && !this.Emitter.Locals.ContainsKey(varName)) { varName = this.AddLocal(varName, clause.VariableNameToken, clause.Type); } this.Emitter.IgnoreBlock = clause.Body; clause.Body.AcceptVisitor(this.Emitter); Write(JS.Vars.ASYNC_E + " = null;"); this.PopLocals(); this.WriteNewLine(); tryInfo.CatchBlocks.Add(new Tuple <string, string, int, int>(varName, clause.Type.IsNull ? JS.Types.System.Exception.NAME : BridgeTypes.ToJsName(clause.Type, this.Emitter), catchStep.Step, Emitter.AsyncBlock.Steps.Last().Step)); catchSteps.Add(Emitter.AsyncBlock.Steps.Last()); } if (!this.Emitter.Locals.ContainsKey(JS.Vars.ASYNC_E)) { this.AddLocal(JS.Vars.ASYNC_E, null, 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(JS.Vars.ASYNC_JUMP + " > -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(JS.Vars.ASYNC_STEP + " = " + Helpers.PrefixDollar("{", hashcode, "};")); this.WriteNewLine(); this.Write("continue;"); } else { this.Write(JS.Vars.ASYNC_STEP + " = " + JS.Vars.ASYNC_JUMP + ";"); this.WriteNewLine(); this.Write(JS.Vars.ASYNC_JUMP + " = null;"); } this.WriteNewLine(); this.EndBlock(); this.WriteSpace(); this.WriteElse(); this.WriteIf(); this.WriteOpenParentheses(); this.Write(JS.Vars.ASYNC_E); this.WriteCloseParentheses(); this.WriteSpace(); this.BeginBlock(); if (this.Emitter.AsyncBlock.IsTaskReturn) { this.Write(JS.Vars.ASYNC_TCS + "." + JS.Funcs.SET_EXCEPTION + "(" + JS.Vars.ASYNC_E + ");"); } else { this.Write("throw " + JS.Vars.ASYNC_E + ";"); } this.WriteNewLine(); this.WriteReturn(false); this.WriteSemiColon(); this.WriteNewLine(); this.EndBlock(); this.WriteSpace(); this.WriteElse(); this.WriteIf(); this.WriteOpenParentheses(); this.Write(JS.Funcs.BRIDGE_IS_DEFINED); this.WriteOpenParentheses(); this.Write(JS.Vars.ASYNC_RETURN_VALUE); this.WriteCloseParentheses(); 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(JS.Vars.ASYNC_STEP + " = " + Helpers.PrefixDollar("{", hashcode, "};")); this.WriteNewLine(); this.Write("continue;"); } else { this.Write(JS.Vars.ASYNC_TCS + "." + JS.Funcs.SET_RESULT + "(" + JS.Vars.ASYNC_RETURN_VALUE + ");"); this.WriteNewLine(); this.WriteReturn(false); this.WriteSemiColon(); } this.WriteNewLine(); this.EndBlock(); if (!this.Emitter.Locals.ContainsKey(JS.Vars.ASYNC_E)) { this.AddLocal(JS.Vars.ASYNC_E, null, AstType.Null); } } var lastFinallyStep = Emitter.AsyncBlock.Steps.Last(); var nextStep = this.Emitter.AsyncBlock.AddAsyncStep(); if (finalyStep != null) { tryInfo.FinallyStep = finalyStep.Step; lastFinallyStep.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); }