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

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

Issue 2510073002: Provide source map info for simple async methods. (Closed)
Patch Set: Created 4 years, 1 month 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
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;
11 11
12 import '../common.dart'; 12 import '../common.dart';
13 import '../io/source_information.dart' show SourceInformation;
13 import '../util/util.dart' show Pair; 14 import '../util/util.dart' show Pair;
14 import "js.dart" as js; 15 import 'js.dart' as js;
15 16
16 /// Rewrites a [js.Fun] with async/sync*/async* functions and await and yield 17 /// Rewrites a [js.Fun] with async/sync*/async* functions and await and yield
17 /// (with dart-like semantics) to an equivalent function without these. 18 /// (with dart-like semantics) to an equivalent function without these.
18 /// await-for is not handled and must be rewritten before. (Currently handled 19 /// await-for is not handled and must be rewritten before. (Currently handled
19 /// in ssa/builder.dart). 20 /// in ssa/builder.dart).
20 /// 21 ///
21 /// When generating the input to this, special care must be taken that 22 /// When generating the input to this, special care must be taken that
22 /// parameters to sync* functions that are mutated in the body must be boxed. 23 /// parameters to sync* functions that are mutated in the body must be boxed.
23 /// (Currently handled in closure.dart). 24 /// (Currently handled in closure.dart).
24 /// 25 ///
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 513
513 void addFunctionExits() { 514 void addFunctionExits() {
514 addSuccesExit(); 515 addSuccesExit();
515 addErrorExit(); 516 addErrorExit();
516 } 517 }
517 518
518 /// Returns the rewritten function. 519 /// Returns the rewritten function.
519 js.Fun finishFunction( 520 js.Fun finishFunction(
520 List<js.Parameter> parameters, 521 List<js.Parameter> parameters,
521 js.Statement rewrittenBody, 522 js.Statement rewrittenBody,
522 js.VariableDeclarationList variableDeclarations); 523 js.VariableDeclarationList variableDeclarations,
524 SourceInformation sourceInformation);
523 525
524 Iterable<js.VariableInitialization> variableInitializations(); 526 Iterable<js.VariableInitialization> variableInitializations();
525 527
526 /// Rewrites an async/sync*/async* function to a normal Javascript function. 528 /// Rewrites an async/sync*/async* function to a normal Javascript function.
527 /// 529 ///
528 /// The control flow is flattened by simulating 'goto' using a switch in a 530 /// The control flow is flattened by simulating 'goto' using a switch in a
529 /// loop and a state variable [goto] inside a nested function [body] 531 /// loop and a state variable [goto] inside a nested function [body]
530 /// that can be called back by [asyncStarHelper]/[asyncStarHelper]/the 532 /// that can be called back by [asyncStarHelper]/[asyncStarHelper]/the
531 /// [Iterator]. 533 /// [Iterator].
532 /// 534 ///
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 variables.add(_makeVariableInitializer(self, js.js('this'))); 700 variables.add(_makeVariableInitializer(self, js.js('this')));
699 } 701 }
700 variables.addAll(localVariables.map((js.VariableDeclaration declaration) { 702 variables.addAll(localVariables.map((js.VariableDeclaration declaration) {
701 return new js.VariableInitialization(declaration, null); 703 return new js.VariableInitialization(declaration, null);
702 })); 704 }));
703 variables.addAll(new Iterable.generate(tempVarHighWaterMark, 705 variables.addAll(new Iterable.generate(tempVarHighWaterMark,
704 (int i) => _makeVariableInitializer(useTempVar(i + 1).name, null))); 706 (int i) => _makeVariableInitializer(useTempVar(i + 1).name, null)));
705 js.VariableDeclarationList variableDeclarations = 707 js.VariableDeclarationList variableDeclarations =
706 new js.VariableDeclarationList(variables); 708 new js.VariableDeclarationList(variables);
707 709
708 return finishFunction(node.params, rewrittenBody, variableDeclarations); 710 return finishFunction(node.params, rewrittenBody, variableDeclarations,
711 node.sourceInformation);
709 } 712 }
710 713
711 @override 714 @override
712 js.Expression visitFun(js.Fun node) { 715 js.Expression visitFun(js.Fun node) {
713 if (node.asyncModifier.isAsync || node.asyncModifier.isYielding) { 716 if (node.asyncModifier.isAsync || node.asyncModifier.isYielding) {
714 // The translation does not handle nested functions that are generators 717 // The translation does not handle nested functions that are generators
715 // or asynchronous. These functions should only be ones that are 718 // or asynchronous. These functions should only be ones that are
716 // introduced by JS foreign code from our own libraries. 719 // introduced by JS foreign code from our own libraries.
717 reporter.internalError( 720 reporter.internalError(
718 spannable, 'Nested function is a generator or asynchronous.'); 721 spannable, 'Nested function is a generator or asynchronous.');
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
844 return; 847 return;
845 } 848 }
846 translateJump(target, breakLabels[target]); 849 translateJump(target, breakLabels[target]);
847 } 850 }
848 851
849 @override 852 @override
850 js.Expression visitCall(js.Call node) { 853 js.Expression visitCall(js.Call node) {
851 bool storeTarget = node.arguments.any(shouldTransform); 854 bool storeTarget = node.arguments.any(shouldTransform);
852 return withCallTargetExpression(node.target, (target) { 855 return withCallTargetExpression(node.target, (target) {
853 return withExpressions(node.arguments, (List<js.Expression> arguments) { 856 return withExpressions(node.arguments, (List<js.Expression> arguments) {
854 return new js.Call(target, arguments); 857 return new js.Call(target, arguments)
858 .withSourceInformation(node.sourceInformation);
855 }); 859 });
856 }, store: storeTarget); 860 }, store: storeTarget);
857 } 861 }
858 862
859 @override 863 @override
860 void visitCase(js.Case node) { 864 void visitCase(js.Case node) {
861 return unreachable(node); 865 return unreachable(node);
862 } 866 }
863 867
864 @override 868 @override
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
1398 } 1402 }
1399 1403
1400 @override 1404 @override
1401 js.Expression visitThis(js.This node) { 1405 js.Expression visitThis(js.This node) {
1402 return self; 1406 return self;
1403 } 1407 }
1404 1408
1405 @override 1409 @override
1406 void visitThrow(js.Throw node) { 1410 void visitThrow(js.Throw node) {
1407 withExpression(node.expression, (js.Expression expression) { 1411 withExpression(node.expression, (js.Expression expression) {
1408 addStatement(new js.Throw(expression)); 1412 addStatement(new js.Throw(expression)
1413 .withSourceInformation(node.sourceInformation));
1409 }, store: false); 1414 }, store: false);
1410 } 1415 }
1411 1416
1412 setErrorHandler([int errorHandler]) { 1417 setErrorHandler([int errorHandler]) {
1413 js.Expression label = 1418 js.Expression label =
1414 (errorHandler == null) ? currentErrorHandler : js.number(errorHandler); 1419 (errorHandler == null) ? currentErrorHandler : js.number(errorHandler);
1415 addStatement(js.js.statement('# = #;', [handler, label])); 1420 addStatement(js.js.statement('# = #;', [handler, label]));
1416 } 1421 }
1417 1422
1418 List<int> _finalliesUpToAndEnclosingHandler() { 1423 List<int> _finalliesUpToAndEnclosingHandler() {
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
1705 /// Returning from an async method calls [asyncStarHelper] with the result. 1710 /// Returning from an async method calls [asyncStarHelper] with the result.
1706 /// (the result might have been stored in [returnValue] by some finally 1711 /// (the result might have been stored in [returnValue] by some finally
1707 /// block). 1712 /// block).
1708 void addSuccesExit() { 1713 void addSuccesExit() {
1709 if (analysis.hasExplicitReturns) { 1714 if (analysis.hasExplicitReturns) {
1710 beginLabel(exitLabel); 1715 beginLabel(exitLabel);
1711 } else { 1716 } else {
1712 addStatement(new js.Comment("implicit return")); 1717 addStatement(new js.Comment("implicit return"));
1713 } 1718 }
1714 addStatement(js.js.statement( 1719 addStatement(js.js.statement(
1715 "return #runtimeHelper(#returnValue, #successCode, #completer);", 1720 "return #runtimeHelper(#returnValue, #successCode, #completer);", {
1716 { 1721 "runtimeHelper": asyncHelper,
1717 "runtimeHelper": asyncHelper, 1722 "successCode": js.number(error_codes.SUCCESS),
1718 "successCode": js.number(error_codes.SUCCESS), 1723 "returnValue":
1719 "returnValue": 1724 analysis.hasExplicitReturns ? returnValue : new js.LiteralNull(),
1720 analysis.hasExplicitReturns ? returnValue : new js.LiteralNull(), 1725 "completer": completer
1721 "completer": completer 1726 }));
1722 }));
1723 } 1727 }
1724 1728
1725 @override 1729 @override
1726 Iterable<js.VariableInitialization> variableInitializations() { 1730 Iterable<js.VariableInitialization> variableInitializations() {
1727 List<js.VariableInitialization> variables = 1731 List<js.VariableInitialization> variables =
1728 new List<js.VariableInitialization>(); 1732 new List<js.VariableInitialization>();
1729 variables 1733 variables
1730 .add(_makeVariableInitializer(completer, new js.New(newCompleter, []))); 1734 .add(_makeVariableInitializer(completer, new js.New(newCompleter, [])));
1731 if (analysis.hasExplicitReturns) { 1735 if (analysis.hasExplicitReturns) {
1732 variables.add(_makeVariableInitializer(returnValue, null)); 1736 variables.add(_makeVariableInitializer(returnValue, null));
(...skipping 19 matching lines...) Expand all
1752 "value": value, 1756 "value": value,
1753 "bodyName": bodyName, 1757 "bodyName": bodyName,
1754 "completer": completer 1758 "completer": completer
1755 }); 1759 });
1756 } 1760 }
1757 1761
1758 @override 1762 @override
1759 js.Fun finishFunction( 1763 js.Fun finishFunction(
1760 List<js.Parameter> parameters, 1764 List<js.Parameter> parameters,
1761 js.Statement rewrittenBody, 1765 js.Statement rewrittenBody,
1762 js.VariableDeclarationList variableDeclarations) { 1766 js.VariableDeclarationList variableDeclarations,
1767 SourceInformation sourceInformation) {
1763 return js.js( 1768 return js.js(
1764 """ 1769 """
1765 function (#parameters) { 1770 function (#parameters) {
1766 #variableDeclarations; 1771 #variableDeclarations;
1767 var #bodyName = #wrapBody(function (#errorCode, #result) { 1772 var #bodyName = #wrapBody(function (#errorCode, #result) {
1768 if (#errorCode === #ERROR) { 1773 if (#errorCode === #ERROR) {
1769 #currentError = #result; 1774 #currentError = #result;
1770 #goto = #handler; 1775 #goto = #handler;
1771 } 1776 }
1772 #rewrittenBody; 1777 #rewrittenBody;
1773 }); 1778 });
1774 return #asyncHelper(null, #bodyName, #completer); 1779 return #asyncHelper(null, #bodyName, #completer);
1775 }""", 1780 }""",
1776 { 1781 {
1777 "parameters": parameters, 1782 "parameters": parameters,
1778 "variableDeclarations": variableDeclarations, 1783 "variableDeclarations": variableDeclarations,
1779 "ERROR": js.number(error_codes.ERROR), 1784 "ERROR": js.number(error_codes.ERROR),
1780 "rewrittenBody": rewrittenBody, 1785 "rewrittenBody": rewrittenBody,
1781 "bodyName": bodyName, 1786 "bodyName": bodyName,
1782 "currentError": currentError, 1787 "currentError": currentError,
1783 "goto": goto, 1788 "goto": goto,
1784 "handler": handler, 1789 "handler": handler,
1785 "errorCode": errorCodeName, 1790 "errorCode": errorCodeName,
1786 "result": resultName, 1791 "result": resultName,
1787 "asyncHelper": asyncHelper, 1792 "asyncHelper": asyncHelper,
1788 "completer": completer, 1793 "completer": completer,
1789 "wrapBody": wrapBody, 1794 "wrapBody": wrapBody,
1790 }); 1795 }).withSourceInformation(sourceInformation);
1791 } 1796 }
1792 } 1797 }
1793 1798
1794 class SyncStarRewriter extends AsyncRewriterBase { 1799 class SyncStarRewriter extends AsyncRewriterBase {
1795 bool get isSyncStar => true; 1800 bool get isSyncStar => true;
1796 1801
1797 /// Contructor creating the Iterable for a sync* method. Called with 1802 /// Contructor creating the Iterable for a sync* method. Called with
1798 /// [bodyName]. 1803 /// [bodyName].
1799 final js.Expression newIterable; 1804 final js.Expression newIterable;
1800 1805
(...skipping 30 matching lines...) Expand all
1831 new js.Return(new js.Call(yieldStarExpression, [expression]))); 1836 new js.Return(new js.Call(yieldStarExpression, [expression])));
1832 } else { 1837 } else {
1833 addStatement(new js.Return(expression)); 1838 addStatement(new js.Return(expression));
1834 } 1839 }
1835 } 1840 }
1836 1841
1837 @override 1842 @override
1838 js.Fun finishFunction( 1843 js.Fun finishFunction(
1839 List<js.Parameter> parameters, 1844 List<js.Parameter> parameters,
1840 js.Statement rewrittenBody, 1845 js.Statement rewrittenBody,
1841 js.VariableDeclarationList variableDeclarations) { 1846 js.VariableDeclarationList variableDeclarations,
1847 SourceInformation sourceInformation) {
1842 // Each iterator invocation on the iterable should work on its own copy of 1848 // Each iterator invocation on the iterable should work on its own copy of
1843 // the parameters. 1849 // the parameters.
1844 // TODO(sigurdm): We only need to do this copying for parameters that are 1850 // TODO(sigurdm): We only need to do this copying for parameters that are
1845 // mutated. 1851 // mutated.
1846 List<js.VariableInitialization> declarations = 1852 List<js.VariableInitialization> declarations =
1847 new List<js.VariableInitialization>(); 1853 new List<js.VariableInitialization>();
1848 List<js.Parameter> renamedParameters = new List<js.Parameter>(); 1854 List<js.Parameter> renamedParameters = new List<js.Parameter>();
1849 for (js.Parameter parameter in parameters) { 1855 for (js.Parameter parameter in parameters) {
1850 String name = parameter.name; 1856 String name = parameter.name;
1851 String renamedName = freshName(name); 1857 String renamedName = freshName(name);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1884 "varDecl": variableDeclarations, 1890 "varDecl": variableDeclarations,
1885 "errorCode": errorCodeName, 1891 "errorCode": errorCodeName,
1886 "newIterable": newIterable, 1892 "newIterable": newIterable,
1887 "body": bodyName, 1893 "body": bodyName,
1888 "self": selfName, 1894 "self": selfName,
1889 "result": resultName, 1895 "result": resultName,
1890 "goto": goto, 1896 "goto": goto,
1891 "handler": handler, 1897 "handler": handler,
1892 "currentError": currentErrorName, 1898 "currentError": currentErrorName,
1893 "ERROR": js.number(error_codes.ERROR), 1899 "ERROR": js.number(error_codes.ERROR),
1894 }); 1900 }).withSourceInformation(sourceInformation);
1895 } 1901 }
1896 1902
1897 void addErrorExit() { 1903 void addErrorExit() {
1898 beginLabel(rethrowLabel); 1904 beginLabel(rethrowLabel);
1899 addStatement(js.js 1905 addStatement(js.js
1900 .statement('return #(#);', [uncaughtErrorExpression, currentError])); 1906 .statement('return #(#);', [uncaughtErrorExpression, currentError]));
1901 } 1907 }
1902 1908
1903 /// Returning from a sync* function returns an [endOfIteration] marker. 1909 /// Returning from a sync* function returns an [endOfIteration] marker.
1904 void addSuccesExit() { 1910 void addSuccesExit() {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2023 "expression": expression, 2029 "expression": expression,
2024 "bodyName": bodyName, 2030 "bodyName": bodyName,
2025 "controller": controllerName, 2031 "controller": controllerName,
2026 })); 2032 }));
2027 } 2033 }
2028 2034
2029 @override 2035 @override
2030 js.Fun finishFunction( 2036 js.Fun finishFunction(
2031 List<js.Parameter> parameters, 2037 List<js.Parameter> parameters,
2032 js.Statement rewrittenBody, 2038 js.Statement rewrittenBody,
2033 js.VariableDeclarationList variableDeclarations) { 2039 js.VariableDeclarationList variableDeclarations,
2040 SourceInformation sourceInformation) {
2034 return js.js( 2041 return js.js(
2035 """ 2042 """
2036 function (#parameters) { 2043 function (#parameters) {
2037 var #bodyName = #wrapBody(function (#errorCode, #result) { 2044 var #bodyName = #wrapBody(function (#errorCode, #result) {
2038 if (#hasYield) { 2045 if (#hasYield) {
2039 switch (#errorCode) { 2046 switch (#errorCode) {
2040 case #STREAM_WAS_CANCELED: 2047 case #STREAM_WAS_CANCELED:
2041 #next = #nextWhenCanceled; 2048 #next = #nextWhenCanceled;
2042 #goto = #next.pop(); 2049 #goto = #next.pop();
2043 break; 2050 break;
(...skipping 23 matching lines...) Expand all
2067 "currentError": currentError, 2074 "currentError": currentError,
2068 "goto": goto, 2075 "goto": goto,
2069 "handler": handler, 2076 "handler": handler,
2070 "next": next, 2077 "next": next,
2071 "nextWhenCanceled": nextWhenCanceled, 2078 "nextWhenCanceled": nextWhenCanceled,
2072 "errorCode": errorCodeName, 2079 "errorCode": errorCodeName,
2073 "result": resultName, 2080 "result": resultName,
2074 "streamOfController": streamOfController, 2081 "streamOfController": streamOfController,
2075 "controller": controllerName, 2082 "controller": controllerName,
2076 "wrapBody": wrapBody, 2083 "wrapBody": wrapBody,
2077 }); 2084 }).withSourceInformation(sourceInformation);
2078 } 2085 }
2079 2086
2080 @override 2087 @override
2081 void addErrorExit() { 2088 void addErrorExit() {
2082 beginLabel(rethrowLabel); 2089 beginLabel(rethrowLabel);
2083 addStatement(js.js.statement( 2090 addStatement(js.js.statement(
2084 "return #asyncHelper(#currentError, #errorCode, #controller);", { 2091 "return #asyncHelper(#currentError, #errorCode, #controller);", {
2085 "asyncHelper": asyncStarHelper, 2092 "asyncHelper": asyncStarHelper,
2086 "errorCode": js.number(error_codes.ERROR), 2093 "errorCode": js.number(error_codes.ERROR),
2087 "currentError": currentError, 2094 "currentError": currentError,
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after
2585 return condition || body; 2592 return condition || body;
2586 } 2593 }
2587 2594
2588 @override 2595 @override
2589 bool visitDartYield(js.DartYield node) { 2596 bool visitDartYield(js.DartYield node) {
2590 hasYield = true; 2597 hasYield = true;
2591 visit(node.expression); 2598 visit(node.expression);
2592 return true; 2599 return true;
2593 } 2600 }
2594 } 2601 }
OLDNEW
« no previous file with comments | « no previous file | tests/compiler/dart2js/sourcemaps/diff.dart » ('j') | tests/compiler/dart2js/sourcemaps/stacktrace_test.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698