Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 tree_ir.optimization.statement_rewriter; | 5 library tree_ir.optimization.statement_rewriter; |
| 6 | 6 |
| 7 import 'optimization.dart' show Pass; | 7 import 'optimization.dart' show Pass; |
| 8 import '../tree_ir_nodes.dart'; | 8 import '../tree_ir_nodes.dart'; |
| 9 import '../../io/source_information.dart'; | 9 import '../../io/source_information.dart'; |
| 10 import '../../elements/elements.dart'; | 10 import '../../elements/elements.dart'; |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 271 @override | 271 @override |
| 272 Expression visitVariableUse(VariableUse node) { | 272 Expression visitVariableUse(VariableUse node) { |
| 273 // Count of number of unseen uses remaining. | 273 // Count of number of unseen uses remaining. |
| 274 unseenUses.putIfAbsent(node.variable, () => node.variable.readCount); | 274 unseenUses.putIfAbsent(node.variable, () => node.variable.readCount); |
| 275 --unseenUses[node.variable]; | 275 --unseenUses[node.variable]; |
| 276 | 276 |
| 277 // We traverse the tree right-to-left, so when we have seen all uses, | 277 // We traverse the tree right-to-left, so when we have seen all uses, |
| 278 // it means we are looking at the first use. | 278 // it means we are looking at the first use. |
| 279 assert(unseenUses[node.variable] < node.variable.readCount); | 279 assert(unseenUses[node.variable] < node.variable.readCount); |
| 280 assert(unseenUses[node.variable] >= 0); | 280 assert(unseenUses[node.variable] >= 0); |
| 281 | |
| 282 // We cannot reliably find the first dynamic use of a variable that is | |
| 283 // accessed from a JS function in a foreign code fragment. | |
| 284 if (node.variable.isCaptured) return node; | |
| 285 | |
| 281 bool isFirstUse = unseenUses[node.variable] == 0; | 286 bool isFirstUse = unseenUses[node.variable] == 0; |
| 282 | 287 |
| 283 // Propagate constant to use site. | 288 // Propagate constant to use site. |
| 284 Expression constant = constantEnvironment[node.variable]; | 289 Expression constant = constantEnvironment[node.variable]; |
| 285 if (constant != null && !hasUnsafeVariableUse(constant)) { | 290 if (constant != null && !hasUnsafeVariableUse(constant)) { |
| 286 --node.variable.readCount; | 291 --node.variable.readCount; |
| 287 return visitExpression(constant); | 292 return visitExpression(constant); |
| 288 } | 293 } |
| 289 | 294 |
| 290 // Try to propagate another expression into this variable use. | 295 // Try to propagate another expression into this variable use. |
| (...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1132 } | 1137 } |
| 1133 | 1138 |
| 1134 Expression makeCondition(Expression e, bool polarity) { | 1139 Expression makeCondition(Expression e, bool polarity) { |
| 1135 return polarity ? e : new Not(e); | 1140 return polarity ? e : new Not(e); |
| 1136 } | 1141 } |
| 1137 | 1142 |
| 1138 Statement getBranch(If node, bool polarity) { | 1143 Statement getBranch(If node, bool polarity) { |
| 1139 return polarity ? node.thenStatement : node.elseStatement; | 1144 return polarity ? node.thenStatement : node.elseStatement; |
| 1140 } | 1145 } |
| 1141 | 1146 |
| 1147 void handleForeignCode(ForeignCode node) { | |
| 1148 // Arguments will get inserted in a JS code template. The arguments will | |
| 1149 // not always be evaluated (e.g. if the template is '# && #'). | |
| 1150 // TODO(asgerf): We could analyze the JS AST to see if arguments are | |
| 1151 // definitely evaluated left-to-right. | |
|
sra1
2015/11/12 02:30:08
We need to do this. The cost on code quality of no
asgerf
2015/11/12 12:09:46
I think we can encode the whole thing with an inte
| |
| 1152 inEmptyEnvironment(() { | |
| 1153 _rewriteList(node.arguments); | |
| 1154 }); | |
| 1155 } | |
| 1156 | |
| 1142 @override | 1157 @override |
| 1143 Expression visitForeignExpression(ForeignExpression node) { | 1158 Expression visitForeignExpression(ForeignExpression node) { |
| 1144 _rewriteList(node.arguments); | 1159 handleForeignCode(node); |
| 1145 return node; | 1160 return node; |
| 1146 } | 1161 } |
| 1147 | 1162 |
| 1148 @override | 1163 @override |
| 1149 Statement visitForeignStatement(ForeignStatement node) { | 1164 Statement visitForeignStatement(ForeignStatement node) { |
| 1150 _rewriteList(node.arguments); | 1165 handleForeignCode(node); |
| 1151 return node; | 1166 return node; |
| 1152 } | 1167 } |
| 1153 | 1168 |
| 1154 @override | 1169 @override |
| 1155 Expression visitAwait(Await node) { | 1170 Expression visitAwait(Await node) { |
| 1156 node.input = visitExpression(node.input); | 1171 node.input = visitExpression(node.input); |
| 1157 return node; | 1172 return node; |
| 1158 } | 1173 } |
| 1159 | 1174 |
| 1160 @override | 1175 @override |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1253 VariableUseVisitor(this.callback); | 1268 VariableUseVisitor(this.callback); |
| 1254 | 1269 |
| 1255 visitVariableUse(VariableUse use) => callback(use); | 1270 visitVariableUse(VariableUse use) => callback(use); |
| 1256 | 1271 |
| 1257 visitInnerFunction(FunctionDefinition node) {} | 1272 visitInnerFunction(FunctionDefinition node) {} |
| 1258 | 1273 |
| 1259 static void visit(Expression node, VariableUseCallback callback) { | 1274 static void visit(Expression node, VariableUseCallback callback) { |
| 1260 new VariableUseVisitor(callback).visitExpression(node); | 1275 new VariableUseVisitor(callback).visitExpression(node); |
| 1261 } | 1276 } |
| 1262 } | 1277 } |
| OLD | NEW |