Index: pkg/compiler/lib/src/js/rewrite_async.dart |
diff --git a/pkg/compiler/lib/src/js/rewrite_async.dart b/pkg/compiler/lib/src/js/rewrite_async.dart |
index b1918ad5ecded07ba04bedb2ededf87029f64c21..06437d7b5bf1b3bd76787daa1b3ae261e5592458 100644 |
--- a/pkg/compiler/lib/src/js/rewrite_async.dart |
+++ b/pkg/compiler/lib/src/js/rewrite_async.dart |
@@ -127,6 +127,14 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
js.VariableUse get handler => new js.VariableUse(handlerName); |
String handlerName; |
+ /// Set to `true` if any of the switch statement labels is a handler. At the |
+ /// end of rewriting this is used to see if a shorter form of error handling |
+ /// can be used. The shorter form could be a change in the method boilerplate, |
+ /// in the state machine wrapper, or not implemented. [addErrorExit] can test |
+ /// this to elide the error exit handler when there are no other handlers, or |
+ /// set it to `true` if there is no shorter form. |
+ bool hasHandlerLabels = false; |
+ |
/// A stack of labels of finally blocks to visit, and the label to go to after |
/// the last. |
js.VariableUse get next => new js.VariableUse(nextName); |
@@ -685,8 +693,10 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
variables.add(_makeVariableInitializer(goto, js.number(0))); |
variables.addAll(variableInitializations()); |
- variables.add(_makeVariableInitializer(handler, js.number(rethrowLabel))); |
- variables.add(_makeVariableInitializer(currentError, null)); |
+ if (hasHandlerLabels) { |
+ variables.add(_makeVariableInitializer(handler, js.number(rethrowLabel))); |
+ variables.add(_makeVariableInitializer(currentError, null)); |
+ } |
if (analysis.hasFinally || (isAsyncStar && analysis.hasYield)) { |
variables.add(_makeVariableInitializer( |
next, new js.ArrayInitializer(<js.Expression>[]))); |
@@ -1412,6 +1422,7 @@ abstract class AsyncRewriterBase extends js.NodeVisitor { |
} |
setErrorHandler([int errorHandler]) { |
+ hasHandlerLabels = true; // TODO(sra): Add short form error handler. |
js.Expression label = |
(errorHandler == null) ? currentErrorHandler : js.number(errorHandler); |
addStatement(js.js.statement('# = #;', [handler, label])); |
@@ -1708,6 +1719,7 @@ class AsyncRewriter extends AsyncRewriterBase { |
} |
void addErrorExit() { |
+ if (!hasHandlerLabels) return; // rethrow handled in method boilerplate. |
beginLabel(rethrowLabel); |
addStatement(js.js.statement( |
"return #thenHelper(#currentError, #completer);", { |
@@ -1777,8 +1789,11 @@ class AsyncRewriter extends AsyncRewriterBase { |
#variableDeclarations; |
var #bodyName = #wrapBody(function (#errorCode, #result) { |
if (#errorCode === #ERROR) { |
- #currentError = #result; |
- #goto = #handler; |
+ if (#hasHandlerLabels) { |
+ #currentError = #result; |
+ #goto = #handler; |
+ } else |
+ return #asyncRethrow(#result, #completer); |
} |
#rewrittenBody; |
}); |
@@ -1796,6 +1811,8 @@ class AsyncRewriter extends AsyncRewriterBase { |
"errorCode": errorCodeName, |
"result": resultName, |
"asyncStart": asyncStart, |
+ "asyncRethrow": asyncRethrow, |
+ "hasHandlerLabels": hasHandlerLabels, |
"completer": completer, |
"wrapBody": wrapBody, |
}).withSourceInformation(sourceInformation); |
@@ -1907,6 +1924,7 @@ class SyncStarRewriter extends AsyncRewriterBase { |
} |
void addErrorExit() { |
+ hasHandlerLabels = true; // TODO(sra): Add short form error handler. |
beginLabel(rethrowLabel); |
addStatement(js.js |
.statement('return #(#);', [uncaughtErrorExpression, currentError])); |
@@ -2091,6 +2109,7 @@ class AsyncStarRewriter extends AsyncRewriterBase { |
@override |
void addErrorExit() { |
+ hasHandlerLabels = true; |
beginLabel(rethrowLabel); |
addStatement(js.js.statement( |
"return #asyncHelper(#currentError, #errorCode, #controller);", { |