| 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 '../diagnostics/invariant.dart' show | 7 import '../diagnostics/invariant.dart' show |
| 8 InternalErrorFunction; | 8 InternalErrorFunction; |
| 9 import '../diagnostics/spannable.dart' show | 9 import '../diagnostics/spannable.dart' show |
| 10 CURRENT_ELEMENT_SPANNABLE; | 10 CURRENT_ELEMENT_SPANNABLE; |
| 11 import '../elements/elements.dart'; | 11 import '../elements/elements.dart'; |
| 12 import '../cps_ir/cps_ir_nodes.dart' as cps_ir; | 12 import '../cps_ir/cps_ir_nodes.dart' as cps_ir; |
| 13 import 'tree_ir_nodes.dart'; | 13 import 'tree_ir_nodes.dart'; |
| 14 import '../constants/values.dart'; |
| 14 | 15 |
| 15 typedef Statement NodeCallback(Statement next); | 16 typedef Statement NodeCallback(Statement next); |
| 16 | 17 |
| 17 /** | 18 /** |
| 18 * Builder translates from CPS-based IR to direct-style Tree. | 19 * Builder translates from CPS-based IR to direct-style Tree. |
| 19 * | 20 * |
| 20 * A call `Invoke(fun, cont, args)`, where cont is a singly-referenced | 21 * A call `Invoke(fun, cont, args)`, where cont is a singly-referenced |
| 21 * non-exit continuation `Cont(v, body)` is translated into a direct-style call | 22 * non-exit continuation `Cont(v, body)` is translated into a direct-style call |
| 22 * whose value is bound in the continuation body: | 23 * whose value is bound in the continuation body: |
| 23 * | 24 * |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 return result; | 271 return result; |
| 271 } | 272 } |
| 272 | 273 |
| 273 /// Translates a CPS primitive to a tree expression. | 274 /// Translates a CPS primitive to a tree expression. |
| 274 /// | 275 /// |
| 275 /// This simply calls the visit method for the primitive. | 276 /// This simply calls the visit method for the primitive. |
| 276 Expression translatePrimitive(cps_ir.Primitive prim) { | 277 Expression translatePrimitive(cps_ir.Primitive prim) { |
| 277 return prim.accept(this); | 278 return prim.accept(this); |
| 278 } | 279 } |
| 279 | 280 |
| 280 /// Translates a condition to a tree expression. | |
| 281 Expression translateCondition(cps_ir.Condition condition) { | |
| 282 cps_ir.IsTrue isTrue = condition; | |
| 283 return getVariableUse(isTrue.value); | |
| 284 } | |
| 285 | |
| 286 /************************ INTERIOR EXPRESSIONS ************************/ | 281 /************************ INTERIOR EXPRESSIONS ************************/ |
| 287 // | 282 // |
| 288 // Visit methods for interior expressions must return a function: | 283 // Visit methods for interior expressions must return a function: |
| 289 // | 284 // |
| 290 // (Statement next) => <result statement> | 285 // (Statement next) => <result statement> |
| 291 // | 286 // |
| 292 | 287 |
| 293 NodeCallback visitLetPrim(cps_ir.LetPrim node) => (Statement next) { | 288 NodeCallback visitLetPrim(cps_ir.LetPrim node) => (Statement next) { |
| 294 Variable variable = getVariable(node.primitive); | 289 Variable variable = getVariable(node.primitive); |
| 295 Expression value = translatePrimitive(node.primitive); | 290 Expression value = translatePrimitive(node.primitive); |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 translateExpression(cont.body)); | 488 translateExpression(cont.body)); |
| 494 } else { | 489 } else { |
| 495 return cont.hasExactlyOneUse && !node.isEscapingTry | 490 return cont.hasExactlyOneUse && !node.isEscapingTry |
| 496 ? translateExpression(cont.body) | 491 ? translateExpression(cont.body) |
| 497 : new Break(getLabel(cont)); | 492 : new Break(getLabel(cont)); |
| 498 } | 493 } |
| 499 }); | 494 }); |
| 500 } | 495 } |
| 501 } | 496 } |
| 502 | 497 |
| 498 /// Translates a branch condition to a tree expression. |
| 499 Expression translateCondition(cps_ir.Branch branch) { |
| 500 Expression value = getVariableUse(branch.condition); |
| 501 if (branch.isStrictCheck) { |
| 502 return new ApplyBuiltinOperator( |
| 503 BuiltinOperator.StrictEq, |
| 504 <Expression>[value, new Constant(new TrueConstantValue())]); |
| 505 } else { |
| 506 return value; |
| 507 } |
| 508 } |
| 509 |
| 503 Statement visitBranch(cps_ir.Branch node) { | 510 Statement visitBranch(cps_ir.Branch node) { |
| 504 Expression condition = translateCondition(node.condition); | 511 Expression condition = translateCondition(node); |
| 505 Statement thenStatement, elseStatement; | 512 Statement thenStatement, elseStatement; |
| 506 cps_ir.Continuation cont = node.trueContinuation.definition; | 513 cps_ir.Continuation cont = node.trueContinuation.definition; |
| 507 assert(cont.parameters.isEmpty); | 514 assert(cont.parameters.isEmpty); |
| 508 thenStatement = cont.hasExactlyOneUse | 515 thenStatement = cont.hasExactlyOneUse |
| 509 ? translateExpression(cont.body) | 516 ? translateExpression(cont.body) |
| 510 : new Break(labels[cont]); | 517 : new Break(labels[cont]); |
| 511 cont = node.falseContinuation.definition; | 518 cont = node.falseContinuation.definition; |
| 512 assert(cont.parameters.isEmpty); | 519 assert(cont.parameters.isEmpty); |
| 513 elseStatement = cont.hasExactlyOneUse | 520 elseStatement = cont.hasExactlyOneUse |
| 514 ? translateExpression(cont.body) | 521 ? translateExpression(cont.body) |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 unexpectedNode(cps_ir.Node node) { | 680 unexpectedNode(cps_ir.Node node) { |
| 674 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node'); | 681 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node'); |
| 675 } | 682 } |
| 676 | 683 |
| 677 visitFunctionDefinition(cps_ir.FunctionDefinition node) { | 684 visitFunctionDefinition(cps_ir.FunctionDefinition node) { |
| 678 unexpectedNode(node); | 685 unexpectedNode(node); |
| 679 } | 686 } |
| 680 visitParameter(cps_ir.Parameter node) => unexpectedNode(node); | 687 visitParameter(cps_ir.Parameter node) => unexpectedNode(node); |
| 681 visitContinuation(cps_ir.Continuation node) => unexpectedNode(node); | 688 visitContinuation(cps_ir.Continuation node) => unexpectedNode(node); |
| 682 visitMutableVariable(cps_ir.MutableVariable node) => unexpectedNode(node); | 689 visitMutableVariable(cps_ir.MutableVariable node) => unexpectedNode(node); |
| 683 visitIsTrue(cps_ir.IsTrue node) => unexpectedNode(node); | |
| 684 } | 690 } |
| 685 | 691 |
| OLD | NEW |