| 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_builder; | 5 library tree_ir_builder; |
| 6 | 6 |
| 7 import '../dart2jslib.dart' as dart2js; | 7 import '../dart2jslib.dart' as dart2js; |
| 8 import '../dart_types.dart'; | 8 import '../dart_types.dart'; |
| 9 import '../elements/elements.dart'; | 9 import '../elements/elements.dart'; |
| 10 import '../cps_ir/cps_ir_nodes.dart' as cps_ir; | 10 import '../cps_ir/cps_ir_nodes.dart' as cps_ir; |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 } else { | 338 } else { |
| 339 return new Assign(variable, definition, visit(node.body)); | 339 return new Assign(variable, definition, visit(node.body)); |
| 340 } | 340 } |
| 341 } | 341 } |
| 342 | 342 |
| 343 Statement visitRunnableBody(cps_ir.RunnableBody node) { | 343 Statement visitRunnableBody(cps_ir.RunnableBody node) { |
| 344 return visit(node.body); | 344 return visit(node.body); |
| 345 } | 345 } |
| 346 | 346 |
| 347 Statement visitLetCont(cps_ir.LetCont node) { | 347 Statement visitLetCont(cps_ir.LetCont node) { |
| 348 Label label; | 348 // Introduce labels for continuations that need them. |
| 349 if (node.continuation.hasMultipleUses) { | 349 for (cps_ir.Continuation continuation in node.continuations) { |
| 350 label = new Label(); | 350 if (continuation.hasMultipleUses) { |
| 351 labels[node.continuation] = label; | 351 labels[continuation] = new Label(); |
| 352 } |
| 352 } | 353 } |
| 353 Statement body = visit(node.body); | 354 Statement body = visit(node.body); |
| 354 // The continuation's body is not always translated directly here because | 355 // Continuations are bound at the same level, but they have to be |
| 355 // it may have been already translated: | 356 // translated as if nested. This is because the body can invoke any |
| 357 // of them from anywhere, so it must be nested inside all of them. |
| 358 // |
| 359 // The continuation bodies are not always translated directly here because |
| 360 // they may have been already translated: |
| 356 // * For singly-used continuations, the continuation's body is | 361 // * For singly-used continuations, the continuation's body is |
| 357 // translated at the site of the continuation invocation. | 362 // translated at the site of the continuation invocation. |
| 358 // * For recursive continuations, there is a single non-recursive | 363 // * For recursive continuations, there is a single non-recursive |
| 359 // invocation. The continuation's body is translated at the site | 364 // invocation. The continuation's body is translated at the site |
| 360 // of the non-recursive continuation invocation. | 365 // of the non-recursive continuation invocation. |
| 361 // See visitInvokeContinuation for the implementation. | 366 // See visitInvokeContinuation for the implementation. |
| 362 if (label == null || node.continuation.isRecursive) return body; | 367 Statement current = body; |
| 363 return new LabeledStatement(label, body, visit(node.continuation.body)); | 368 for (cps_ir.Continuation continuation in node.continuations.reversed) { |
| 369 Label label = labels[continuation]; |
| 370 if (label != null && !continuation.isRecursive) { |
| 371 current = |
| 372 new LabeledStatement(label, current, visit(continuation.body)); |
| 373 } |
| 374 } |
| 375 return current; |
| 364 } | 376 } |
| 365 | 377 |
| 366 Statement visitInvokeStatic(cps_ir.InvokeStatic node) { | 378 Statement visitInvokeStatic(cps_ir.InvokeStatic node) { |
| 367 // Calls are translated to direct style. | 379 // Calls are translated to direct style. |
| 368 List<Expression> arguments = translateArguments(node.arguments); | 380 List<Expression> arguments = translateArguments(node.arguments); |
| 369 Expression invoke = new InvokeStatic(node.target, node.selector, arguments); | 381 Expression invoke = new InvokeStatic(node.target, node.selector, arguments); |
| 370 return continueWithExpression(node.continuation, invoke); | 382 return continueWithExpression(node.continuation, invoke); |
| 371 } | 383 } |
| 372 | 384 |
| 373 Statement visitInvokeMethod(cps_ir.InvokeMethod node) { | 385 Statement visitInvokeMethod(cps_ir.InvokeMethod node) { |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 // visited. | 556 // visited. |
| 545 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node.'); | 557 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node.'); |
| 546 return null; | 558 return null; |
| 547 } | 559 } |
| 548 | 560 |
| 549 Expression visitIsTrue(cps_ir.IsTrue node) { | 561 Expression visitIsTrue(cps_ir.IsTrue node) { |
| 550 return getVariableReference(node.value); | 562 return getVariableReference(node.value); |
| 551 } | 563 } |
| 552 } | 564 } |
| 553 | 565 |
| OLD | NEW |