Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(521)

Side by Side Diff: pkg/compiler/lib/src/js/rewrite_async.dart

Issue 2856223004: dart2js: Smaller async error sequence when only one handler (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tests/compiler/dart2js/async_await_js_transform_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library rewrite_async; 5 library rewrite_async;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 import 'dart:math' show max; 8 import 'dart:math' show max;
9 9
10 import 'package:js_runtime/shared/async_await_error_codes.dart' as error_codes; 10 import 'package:js_runtime/shared/async_await_error_codes.dart' as error_codes;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 /// 120 ///
121 /// To "goto" a label, the label is assigned to this variable, and break out 121 /// To "goto" a label, the label is assigned to this variable, and break out
122 /// of the switch to take another iteration in the while loop. See [addGoto] 122 /// of the switch to take another iteration in the while loop. See [addGoto]
123 js.VariableUse get goto => new js.VariableUse(gotoName); 123 js.VariableUse get goto => new js.VariableUse(gotoName);
124 String gotoName; 124 String gotoName;
125 125
126 /// Variable containing the label of the current error handler. 126 /// Variable containing the label of the current error handler.
127 js.VariableUse get handler => new js.VariableUse(handlerName); 127 js.VariableUse get handler => new js.VariableUse(handlerName);
128 String handlerName; 128 String handlerName;
129 129
130 /// Set to `true` if any of the switch statement labels is a handler.
131 bool hasHandlerLabels = false;
132
130 /// A stack of labels of finally blocks to visit, and the label to go to after 133 /// A stack of labels of finally blocks to visit, and the label to go to after
131 /// the last. 134 /// the last.
132 js.VariableUse get next => new js.VariableUse(nextName); 135 js.VariableUse get next => new js.VariableUse(nextName);
133 String nextName; 136 String nextName;
134 137
135 /// The current returned value (a finally block may overwrite it). 138 /// The current returned value (a finally block may overwrite it).
136 js.VariableUse get returnValue => new js.VariableUse(returnValueName); 139 js.VariableUse get returnValue => new js.VariableUse(returnValueName);
137 String returnValueName; 140 String returnValueName;
138 141
139 /// Stores the current error when we are in the process of handling an error. 142 /// Stores the current error when we are in the process of handling an error.
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 }).toList(); 681 }).toList();
679 js.Statement rewrittenBody = new js.Switch(goto, clauses); 682 js.Statement rewrittenBody = new js.Switch(goto, clauses);
680 if (hasJumpThoughOuterLabel) { 683 if (hasJumpThoughOuterLabel) {
681 rewrittenBody = new js.LabeledStatement(outerLabelName, rewrittenBody); 684 rewrittenBody = new js.LabeledStatement(outerLabelName, rewrittenBody);
682 } 685 }
683 rewrittenBody = js.js.statement('while (true) {#}', rewrittenBody); 686 rewrittenBody = js.js.statement('while (true) {#}', rewrittenBody);
684 List<js.VariableInitialization> variables = <js.VariableInitialization>[]; 687 List<js.VariableInitialization> variables = <js.VariableInitialization>[];
685 688
686 variables.add(_makeVariableInitializer(goto, js.number(0))); 689 variables.add(_makeVariableInitializer(goto, js.number(0)));
687 variables.addAll(variableInitializations()); 690 variables.addAll(variableInitializations());
688 variables.add(_makeVariableInitializer(handler, js.number(rethrowLabel))); 691 if (hasHandlerLabels) {
689 variables.add(_makeVariableInitializer(currentError, null)); 692 variables.add(_makeVariableInitializer(handler, js.number(rethrowLabel)));
693 variables.add(_makeVariableInitializer(currentError, null));
694 }
690 if (analysis.hasFinally || (isAsyncStar && analysis.hasYield)) { 695 if (analysis.hasFinally || (isAsyncStar && analysis.hasYield)) {
691 variables.add(_makeVariableInitializer( 696 variables.add(_makeVariableInitializer(
692 next, new js.ArrayInitializer(<js.Expression>[]))); 697 next, new js.ArrayInitializer(<js.Expression>[])));
693 } 698 }
694 if (analysis.hasThis && !isSyncStar) { 699 if (analysis.hasThis && !isSyncStar) {
695 // Sync* functions must remember `this` on the level of the outer 700 // Sync* functions must remember `this` on the level of the outer
696 // function. 701 // function.
697 variables.add(_makeVariableInitializer(self, js.js('this'))); 702 variables.add(_makeVariableInitializer(self, js.js('this')));
698 } 703 }
699 variables.addAll(localVariables.map((js.VariableDeclaration declaration) { 704 variables.addAll(localVariables.map((js.VariableDeclaration declaration) {
(...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after
1405 1410
1406 @override 1411 @override
1407 void visitThrow(js.Throw node) { 1412 void visitThrow(js.Throw node) {
1408 withExpression(node.expression, (js.Expression expression) { 1413 withExpression(node.expression, (js.Expression expression) {
1409 addStatement(new js.Throw(expression) 1414 addStatement(new js.Throw(expression)
1410 .withSourceInformation(node.sourceInformation)); 1415 .withSourceInformation(node.sourceInformation));
1411 }, store: false); 1416 }, store: false);
1412 } 1417 }
1413 1418
1414 setErrorHandler([int errorHandler]) { 1419 setErrorHandler([int errorHandler]) {
1420 hasHandlerLabels = true;
1415 js.Expression label = 1421 js.Expression label =
1416 (errorHandler == null) ? currentErrorHandler : js.number(errorHandler); 1422 (errorHandler == null) ? currentErrorHandler : js.number(errorHandler);
1417 addStatement(js.js.statement('# = #;', [handler, label])); 1423 addStatement(js.js.statement('# = #;', [handler, label]));
1418 } 1424 }
1419 1425
1420 List<int> _finalliesUpToAndEnclosingHandler() { 1426 List<int> _finalliesUpToAndEnclosingHandler() {
1421 List<int> result = <int>[]; 1427 List<int> result = <int>[];
1422 for (int i = jumpTargets.length - 1; i >= 0; i--) { 1428 for (int i = jumpTargets.length - 1; i >= 0; i--) {
1423 js.Node node = jumpTargets[i]; 1429 js.Node node = jumpTargets[i];
1424 int handlerLabel = handlerLabels[node]; 1430 int handlerLabel = handlerLabels[node];
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
1701 String safeVariableName(String proposedName), 1707 String safeVariableName(String proposedName),
1702 js.Name bodyName}) 1708 js.Name bodyName})
1703 : super(reporter, spannable, safeVariableName, bodyName); 1709 : super(reporter, spannable, safeVariableName, bodyName);
1704 1710
1705 @override 1711 @override
1706 void addYield(js.DartYield node, js.Expression expression) { 1712 void addYield(js.DartYield node, js.Expression expression) {
1707 reporter.internalError(spannable, "Yield in non-generating async function"); 1713 reporter.internalError(spannable, "Yield in non-generating async function");
1708 } 1714 }
1709 1715
1710 void addErrorExit() { 1716 void addErrorExit() {
1717 if (!hasHandlerLabels) return;
1711 beginLabel(rethrowLabel); 1718 beginLabel(rethrowLabel);
1712 addStatement(js.js.statement( 1719 addStatement(js.js.statement(
1713 "return #thenHelper(#currentError, #completer);", { 1720 "return #thenHelper(#currentError, #completer);", {
1714 "thenHelper": asyncRethrow, 1721 "thenHelper": asyncRethrow,
1715 "currentError": currentError, 1722 "currentError": currentError,
1716 "completer": completer 1723 "completer": completer
1717 })); 1724 }));
1718 } 1725 }
1719 1726
1720 /// Returning from an async method calls [asyncStarHelper] with the result. 1727 /// Returning from an async method calls [asyncStarHelper] with the result.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1770 List<js.Parameter> parameters, 1777 List<js.Parameter> parameters,
1771 js.Statement rewrittenBody, 1778 js.Statement rewrittenBody,
1772 js.VariableDeclarationList variableDeclarations, 1779 js.VariableDeclarationList variableDeclarations,
1773 SourceInformation sourceInformation) { 1780 SourceInformation sourceInformation) {
1774 return js.js( 1781 return js.js(
1775 """ 1782 """
1776 function (#parameters) { 1783 function (#parameters) {
1777 #variableDeclarations; 1784 #variableDeclarations;
1778 var #bodyName = #wrapBody(function (#errorCode, #result) { 1785 var #bodyName = #wrapBody(function (#errorCode, #result) {
1779 if (#errorCode === #ERROR) { 1786 if (#errorCode === #ERROR) {
1780 #currentError = #result; 1787 if (#hasHandlerLabels) {
1781 #goto = #handler; 1788 #currentError = #result;
1789 #goto = #handler;
1790 } else
1791 return #asyncRethrow(#result, #completer);
1782 } 1792 }
1783 #rewrittenBody; 1793 #rewrittenBody;
1784 }); 1794 });
1785 return #asyncStart(#bodyName, #completer); 1795 return #asyncStart(#bodyName, #completer);
1786 }""", 1796 }""",
1787 { 1797 {
1788 "parameters": parameters, 1798 "parameters": parameters,
1789 "variableDeclarations": variableDeclarations, 1799 "variableDeclarations": variableDeclarations,
1790 "ERROR": js.number(error_codes.ERROR), 1800 "ERROR": js.number(error_codes.ERROR),
1791 "rewrittenBody": rewrittenBody, 1801 "rewrittenBody": rewrittenBody,
1792 "bodyName": bodyName, 1802 "bodyName": bodyName,
1793 "currentError": currentError, 1803 "currentError": currentError,
1794 "goto": goto, 1804 "goto": goto,
1795 "handler": handler, 1805 "handler": handler,
1796 "errorCode": errorCodeName, 1806 "errorCode": errorCodeName,
1797 "result": resultName, 1807 "result": resultName,
1798 "asyncStart": asyncStart, 1808 "asyncStart": asyncStart,
1809 "asyncRethrow": asyncRethrow,
1810 "hasHandlerLabels": hasHandlerLabels,
1799 "completer": completer, 1811 "completer": completer,
1800 "wrapBody": wrapBody, 1812 "wrapBody": wrapBody,
1801 }).withSourceInformation(sourceInformation); 1813 }).withSourceInformation(sourceInformation);
1802 } 1814 }
1803 } 1815 }
1804 1816
1805 class SyncStarRewriter extends AsyncRewriterBase { 1817 class SyncStarRewriter extends AsyncRewriterBase {
1806 bool get isSyncStar => true; 1818 bool get isSyncStar => true;
1807 1819
1808 /// Constructor creating the Iterable for a sync* method. Called with 1820 /// Constructor creating the Iterable for a sync* method. Called with
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1900 "self": selfName, 1912 "self": selfName,
1901 "result": resultName, 1913 "result": resultName,
1902 "goto": goto, 1914 "goto": goto,
1903 "handler": handler, 1915 "handler": handler,
1904 "currentError": currentErrorName, 1916 "currentError": currentErrorName,
1905 "ERROR": js.number(error_codes.ERROR), 1917 "ERROR": js.number(error_codes.ERROR),
1906 }).withSourceInformation(sourceInformation); 1918 }).withSourceInformation(sourceInformation);
1907 } 1919 }
1908 1920
1909 void addErrorExit() { 1921 void addErrorExit() {
1922 hasHandlerLabels = true;
floitsch 2017/05/04 08:52:05 This is too confusing, but I'm guessing this is ju
sra1 2017/05/05 21:52:34 I added a field comment and a TODO comment here to
1910 beginLabel(rethrowLabel); 1923 beginLabel(rethrowLabel);
1911 addStatement(js.js 1924 addStatement(js.js
1912 .statement('return #(#);', [uncaughtErrorExpression, currentError])); 1925 .statement('return #(#);', [uncaughtErrorExpression, currentError]));
1913 } 1926 }
1914 1927
1915 /// Returning from a sync* function returns an [endOfIteration] marker. 1928 /// Returning from a sync* function returns an [endOfIteration] marker.
1916 void addSuccesExit() { 1929 void addSuccesExit() {
1917 if (analysis.hasExplicitReturns) { 1930 if (analysis.hasExplicitReturns) {
1918 beginLabel(exitLabel); 1931 beginLabel(exitLabel);
1919 } else { 1932 } else {
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
2084 "errorCode": errorCodeName, 2097 "errorCode": errorCodeName,
2085 "result": resultName, 2098 "result": resultName,
2086 "streamOfController": streamOfController, 2099 "streamOfController": streamOfController,
2087 "controller": controllerName, 2100 "controller": controllerName,
2088 "wrapBody": wrapBody, 2101 "wrapBody": wrapBody,
2089 }).withSourceInformation(sourceInformation); 2102 }).withSourceInformation(sourceInformation);
2090 } 2103 }
2091 2104
2092 @override 2105 @override
2093 void addErrorExit() { 2106 void addErrorExit() {
2107 hasHandlerLabels = true;
floitsch 2017/05/04 08:52:05 ditto.
2094 beginLabel(rethrowLabel); 2108 beginLabel(rethrowLabel);
2095 addStatement(js.js.statement( 2109 addStatement(js.js.statement(
2096 "return #asyncHelper(#currentError, #errorCode, #controller);", { 2110 "return #asyncHelper(#currentError, #errorCode, #controller);", {
2097 "asyncHelper": asyncStarHelper, 2111 "asyncHelper": asyncStarHelper,
2098 "errorCode": js.number(error_codes.ERROR), 2112 "errorCode": js.number(error_codes.ERROR),
2099 "currentError": currentError, 2113 "currentError": currentError,
2100 "controller": controllerName 2114 "controller": controllerName
2101 })); 2115 }));
2102 } 2116 }
2103 2117
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
2595 return condition || body; 2609 return condition || body;
2596 } 2610 }
2597 2611
2598 @override 2612 @override
2599 bool visitDartYield(js.DartYield node) { 2613 bool visitDartYield(js.DartYield node) {
2600 hasYield = true; 2614 hasYield = true;
2601 visit(node.expression); 2615 visit(node.expression);
2602 return true; 2616 return true;
2603 } 2617 }
2604 } 2618 }
OLDNEW
« no previous file with comments | « no previous file | tests/compiler/dart2js/async_await_js_transform_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698