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

Side by Side Diff: pkg/compiler/lib/src/js_backend/codegen/codegen.dart

Issue 1075113003: Pull JS assignments into var initializer. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated js_cps_ir_backend test files Created 5 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/compiler/dart2js/js_backend_cps_ir_basic_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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 code_generator; 5 library code_generator;
6 6
7 import 'glue.dart'; 7 import 'glue.dart';
8 8
9 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir; 9 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir;
10 import '../../js/js.dart' as js; 10 import '../../js/js.dart' as js;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 52
53 CodeGenerator(this.glue, this.registry); 53 CodeGenerator(this.glue, this.registry);
54 54
55 /// Generates JavaScript code for the body of [function]. 55 /// Generates JavaScript code for the body of [function].
56 js.Fun buildFunction(tree_ir.FunctionDefinition function) { 56 js.Fun buildFunction(tree_ir.FunctionDefinition function) {
57 currentFunction = function.element; 57 currentFunction = function.element;
58 visitStatement(function.body); 58 visitStatement(function.body);
59 59
60 List<js.Parameter> parameters = new List<js.Parameter>(); 60 List<js.Parameter> parameters = new List<js.Parameter>();
61 Set<tree_ir.Variable> parameterSet = new Set<tree_ir.Variable>(); 61 Set<tree_ir.Variable> parameterSet = new Set<tree_ir.Variable>();
62 Set<String> declaredVariables = new Set<String>();
62 63
63 for (tree_ir.Variable parameter in function.parameters) { 64 for (tree_ir.Variable parameter in function.parameters) {
64 String name = getVariableName(parameter); 65 String name = getVariableName(parameter);
65 parameters.add(new js.Parameter(name)); 66 parameters.add(new js.Parameter(name));
66 parameterSet.add(parameter); 67 parameterSet.add(parameter);
68 declaredVariables.add(name);
67 } 69 }
68 70
69 List<js.VariableInitialization> jsVariables = <js.VariableInitialization>[]; 71 List<js.VariableInitialization> jsVariables = <js.VariableInitialization>[];
70 72
73 // Declare variables with an initializer. Pull statements into the
74 // initializer until we find a statement that cannot be pulled in.
75 int accumulatorIndex = 0;
76 while (accumulatorIndex < accumulator.length) {
77 js.Node node = accumulator[accumulatorIndex];
78
79 // Check that node is an assignment to a local variable.
80 if (node is! js.ExpressionStatement) break;
81 js.ExpressionStatement stmt = node;
82 if (stmt.expression is! js.Assignment) break;
83 js.Assignment assign = stmt.expression;
84 if (assign.leftHandSide is! js.VariableUse) break;
85 if (assign.op != null) break; // Compound assignment.
86 js.VariableUse use = assign.leftHandSide;
87
88 // We cannot declare a variable more than once.
89 if (!declaredVariables.add(use.name)) break;
90
91 js.VariableInitialization jsVariable = new js.VariableInitialization(
92 new js.VariableDeclaration(use.name),
93 assign.value);
94 jsVariables.add(jsVariable);
95
96 ++accumulatorIndex;
97 }
98
99 // Discard the statements that were pulled in the initializer.
100 if (accumulatorIndex > 0) {
101 accumulator = accumulator.sublist(accumulatorIndex);
102 }
103
104 // Declare remaining variables.
71 for (tree_ir.Variable variable in variableNames.keys) { 105 for (tree_ir.Variable variable in variableNames.keys) {
72 if (parameterSet.contains(variable)) continue;
73 String name = getVariableName(variable); 106 String name = getVariableName(variable);
107 if (declaredVariables.contains(name)) continue;
74 js.VariableInitialization jsVariable = new js.VariableInitialization( 108 js.VariableInitialization jsVariable = new js.VariableInitialization(
75 new js.VariableDeclaration(name), 109 new js.VariableDeclaration(name),
76 null); 110 null);
77 jsVariables.add(jsVariable); 111 jsVariables.add(jsVariable);
78 } 112 }
79 113
80 if (jsVariables.length > 0) { 114 if (jsVariables.length > 0) {
81 // Would be nice to avoid inserting at the beginning of list. 115 // Would be nice to avoid inserting at the beginning of list.
82 accumulator.insert(0, new js.ExpressionStatement( 116 accumulator.insert(0, new js.ExpressionStatement(
83 new js.VariableDeclarationList(jsVariables))); 117 new js.VariableDeclarationList(jsVariables)));
(...skipping 16 matching lines...) Expand all
100 // Functions are not nested in the JS backend. 134 // Functions are not nested in the JS backend.
101 assert(variable.host == currentFunction); 135 assert(variable.host == currentFunction);
102 136
103 // Get the name if we already have one. 137 // Get the name if we already have one.
104 String name = variableNames[variable]; 138 String name = variableNames[variable];
105 if (name != null) { 139 if (name != null) {
106 return name; 140 return name;
107 } 141 }
108 142
109 // Synthesize a variable name that isn't used elsewhere. 143 // Synthesize a variable name that isn't used elsewhere.
110 // The [usedVariableNames] set is shared between nested emitters,
111 // so this also prevents clash with variables in an enclosing/inner scope.
112 // The renaming phase after codegen will further prefix local variables
113 // so they cannot clash with top-level variables or fields.
114 String prefix = variable.element == null ? 'v' : variable.element.name; 144 String prefix = variable.element == null ? 'v' : variable.element.name;
115 int counter = 0; 145 int counter = 0;
116 name = glue.safeVariableName(variable.element == null 146 name = glue.safeVariableName(variable.element == null
117 ? '$prefix$counter' 147 ? '$prefix$counter'
118 : variable.element.name); 148 : variable.element.name);
119 while (!usedVariableNames.add(name)) { 149 while (!usedVariableNames.add(name)) {
120 ++counter; 150 ++counter;
121 name = '$prefix$counter'; 151 name = '$prefix$counter';
122 } 152 }
123 variableNames[variable] = name; 153 variableNames[variable] = name;
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 623
594 @override 624 @override
595 visitFunctionDeclaration(tree_ir.FunctionDeclaration node) { 625 visitFunctionDeclaration(tree_ir.FunctionDeclaration node) {
596 return errorUnsupportedNode(node); 626 return errorUnsupportedNode(node);
597 } 627 }
598 628
599 errorUnsupportedNode(tree_ir.DartSpecificNode node) { 629 errorUnsupportedNode(tree_ir.DartSpecificNode node) {
600 throw "Unsupported node in JS backend: $node"; 630 throw "Unsupported node in JS backend: $node";
601 } 631 }
602 } 632 }
OLDNEW
« no previous file with comments | « no previous file | tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698