OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 part of dart2js.ir_builder; | 5 part of dart2js.ir_builder; |
6 | 6 |
7 /** | 7 /** |
8 * This task iterates through all resolved elements and builds [ir.Node]s. The | 8 * This task iterates through all resolved elements and builds [ir.Node]s. The |
9 * nodes are stored in the [nodes] map and accessible through [hasIr] and | 9 * nodes are stored in the [nodes] map and accessible through [hasIr] and |
10 * [getIr]. | 10 * [getIr]. |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 | 233 |
234 visitIf(ast.If node) { | 234 visitIf(ast.If node) { |
235 irBuilder.buildIf( | 235 irBuilder.buildIf( |
236 build(node.condition), | 236 build(node.condition), |
237 subbuild(node.thenPart), | 237 subbuild(node.thenPart), |
238 subbuild(node.elsePart)); | 238 subbuild(node.elsePart)); |
239 } | 239 } |
240 | 240 |
241 ir.Primitive visitLabeledStatement(ast.LabeledStatement node) { | 241 ir.Primitive visitLabeledStatement(ast.LabeledStatement node) { |
242 ast.Statement body = node.statement; | 242 ast.Statement body = node.statement; |
243 return body is ast.Loop | 243 if (body is ast.Loop) return visit(body); |
244 ? visit(body) | 244 JumpTarget target = elements.getTargetDefinition(body); |
245 : giveup(node, 'labeled statement'); | 245 JumpCollector jumps = new JumpCollector(target); |
| 246 irBuilder.state.breakCollectors.add(jumps); |
| 247 IrBuilder innerBuilder = new IrBuilder.delimited(irBuilder); |
| 248 withBuilder(innerBuilder, () { |
| 249 visit(body); |
| 250 }); |
| 251 irBuilder.state.breakCollectors.removeLast(); |
| 252 bool hasBreaks = !jumps.isEmpty; |
| 253 ir.Continuation joinContinuation; |
| 254 if (hasBreaks) { |
| 255 if (innerBuilder.isOpen) { |
| 256 jumps.addJump(innerBuilder); |
| 257 } |
| 258 |
| 259 // All jumps to the break continuation must be in the scope of the |
| 260 // continuation's binding. The continuation is bound just outside the |
| 261 // body to satisfy this property without extra analysis. |
| 262 // As a consequence, the break continuation needs parameters for all |
| 263 // local variables in scope at the exit from the body. |
| 264 List<ir.Parameter> parameters = |
| 265 new List<ir.Parameter>.generate(irBuilder.environment.length, (i) { |
| 266 return new ir.Parameter(irBuilder.environment.index2variable[i]); |
| 267 }); |
| 268 joinContinuation = new ir.Continuation(parameters); |
| 269 irBuilder.invokeFullJoin(joinContinuation, jumps, recursive: false); |
| 270 irBuilder.add(new ir.LetCont(joinContinuation, innerBuilder._root)); |
| 271 for (int i = 0; i < irBuilder.environment.length; ++i) { |
| 272 irBuilder.environment.index2value[i] = parameters[i]; |
| 273 } |
| 274 } else { |
| 275 if (innerBuilder._root != null) { |
| 276 irBuilder.add(innerBuilder._root); |
| 277 irBuilder._current = innerBuilder._current; |
| 278 irBuilder.environment = innerBuilder.environment; |
| 279 } |
| 280 } |
| 281 return null; |
246 } | 282 } |
247 | 283 |
248 visitWhile(ast.While node) { | 284 visitWhile(ast.While node) { |
249 irBuilder.buildWhile( | 285 irBuilder.buildWhile( |
250 buildCondition: subbuild(node.condition), | 286 buildCondition: subbuild(node.condition), |
251 buildBody: subbuild(node.body), | 287 buildBody: subbuild(node.body), |
252 target: elements.getTargetDefinition(node)); | 288 target: elements.getTargetDefinition(node)); |
253 } | 289 } |
254 | 290 |
255 visitForIn(ast.ForIn node) { | 291 visitForIn(ast.ForIn node) { |
(...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
876 node.visitChildren(this); | 912 node.visitChildren(this); |
877 } | 913 } |
878 | 914 |
879 visitFunctionExpression(ast.FunctionExpression node) { | 915 visitFunctionExpression(ast.FunctionExpression node) { |
880 FunctionElement oldFunction = currentFunction; | 916 FunctionElement oldFunction = currentFunction; |
881 currentFunction = elements[node]; | 917 currentFunction = elements[node]; |
882 visit(node.body); | 918 visit(node.body); |
883 currentFunction = oldFunction; | 919 currentFunction = oldFunction; |
884 } | 920 } |
885 } | 921 } |
OLD | NEW |