| 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 'package:js_ast/js_ast.dart' as js; | 7 import 'package:js_ast/js_ast.dart' as js; |
| 8 | 8 |
| 9 import '../common.dart'; | 9 import '../common.dart'; |
| 10 import '../constants/values.dart'; | 10 import '../constants/values.dart'; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 Variable getVariable(cps_ir.Primitive primitive) { | 98 Variable getVariable(cps_ir.Primitive primitive) { |
| 99 primitive = primitive.effectiveDefinition; | 99 primitive = primitive.effectiveDefinition; |
| 100 return primitive2variable.putIfAbsent(primitive, | 100 return primitive2variable.putIfAbsent(primitive, |
| 101 () => new Variable(currentElement, primitive.hint)); | 101 () => new Variable(currentElement, primitive.hint)); |
| 102 } | 102 } |
| 103 | 103 |
| 104 /// Obtains a reference to the tree Variable corresponding to the IR primitive | 104 /// Obtains a reference to the tree Variable corresponding to the IR primitive |
| 105 /// referred to by [reference]. | 105 /// referred to by [reference]. |
| 106 /// This increments the reference count for the given variable, so the | 106 /// This increments the reference count for the given variable, so the |
| 107 /// returned expression must be used in the tree. | 107 /// returned expression must be used in the tree. |
| 108 Expression getVariableUse(cps_ir.Reference<cps_ir.Primitive> reference) { | 108 Expression getVariableUse(cps_ir.Reference<cps_ir.Primitive> reference, |
| 109 {SourceInformation sourceInformation}) { |
| 109 cps_ir.Primitive prim = reference.definition.effectiveDefinition; | 110 cps_ir.Primitive prim = reference.definition.effectiveDefinition; |
| 110 if (prim is cps_ir.Constant && inlinedConstants.contains(prim)) { | 111 if (prim is cps_ir.Constant && inlinedConstants.contains(prim)) { |
| 111 return new Constant(prim.value); | 112 return new Constant(prim.value); |
| 112 } | 113 } |
| 113 if (thisParameter != null && prim == thisParameter) { | 114 if (thisParameter != null && prim == thisParameter) { |
| 114 return new This(); | 115 return new This(); |
| 115 } | 116 } |
| 116 return new VariableUse(getVariable(prim)); | 117 return new VariableUse( |
| 118 getVariable(prim), sourceInformation: sourceInformation); |
| 117 } | 119 } |
| 118 | 120 |
| 119 Expression getVariableUseOrNull( | 121 Expression getVariableUseOrNull( |
| 120 cps_ir.Reference<cps_ir.Primitive> reference) { | 122 cps_ir.Reference<cps_ir.Primitive> reference) { |
| 121 return reference == null ? null : getVariableUse(reference); | 123 return reference == null ? null : getVariableUse(reference); |
| 122 } | 124 } |
| 123 | 125 |
| 124 Label getLabel(cps_ir.Continuation cont) { | 126 Label getLabel(cps_ir.Continuation cont) { |
| 125 return labels.putIfAbsent(cont, () => new Label()); | 127 return labels.putIfAbsent(cont, () => new Label()); |
| 126 } | 128 } |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 return cont.hasExactlyOneUse && !node.isEscapingTry | 446 return cont.hasExactlyOneUse && !node.isEscapingTry |
| 445 ? translateExpression(cont.body) | 447 ? translateExpression(cont.body) |
| 446 : new Break(getLabel(cont)); | 448 : new Break(getLabel(cont)); |
| 447 } | 449 } |
| 448 }); | 450 }); |
| 449 } | 451 } |
| 450 } | 452 } |
| 451 | 453 |
| 452 /// Translates a branch condition to a tree expression. | 454 /// Translates a branch condition to a tree expression. |
| 453 Expression translateCondition(cps_ir.Branch branch) { | 455 Expression translateCondition(cps_ir.Branch branch) { |
| 454 Expression value = getVariableUse(branch.conditionRef); | 456 Expression value = getVariableUse( |
| 457 branch.conditionRef, sourceInformation: branch.sourceInformation); |
| 455 if (branch.isStrictCheck) { | 458 if (branch.isStrictCheck) { |
| 456 return new ApplyBuiltinOperator( | 459 return new ApplyBuiltinOperator( |
| 457 BuiltinOperator.StrictEq, | 460 BuiltinOperator.StrictEq, |
| 458 <Expression>[value, new Constant(new TrueConstantValue())]); | 461 <Expression>[value, new Constant(new TrueConstantValue())], |
| 462 branch.sourceInformation); |
| 459 } else { | 463 } else { |
| 460 return value; | 464 return value; |
| 461 } | 465 } |
| 462 } | 466 } |
| 463 | 467 |
| 464 Statement visitBranch(cps_ir.Branch node) { | 468 Statement visitBranch(cps_ir.Branch node) { |
| 465 Expression condition = translateCondition(node); | 469 Expression condition = translateCondition(node); |
| 466 Statement thenStatement, elseStatement; | 470 Statement thenStatement, elseStatement; |
| 467 cps_ir.Continuation cont = node.trueContinuation; | 471 cps_ir.Continuation cont = node.trueContinuation; |
| 468 assert(cont.parameters.isEmpty); | 472 assert(cont.parameters.isEmpty); |
| 469 thenStatement = cont.hasExactlyOneUse | 473 thenStatement = cont.hasExactlyOneUse |
| 470 ? translateExpression(cont.body) | 474 ? translateExpression(cont.body) |
| 471 : new Break(labels[cont]); | 475 : new Break(labels[cont]); |
| 472 cont = node.falseContinuation; | 476 cont = node.falseContinuation; |
| 473 assert(cont.parameters.isEmpty); | 477 assert(cont.parameters.isEmpty); |
| 474 elseStatement = cont.hasExactlyOneUse | 478 elseStatement = cont.hasExactlyOneUse |
| 475 ? translateExpression(cont.body) | 479 ? translateExpression(cont.body) |
| 476 : new Break(labels[cont]); | 480 : new Break(labels[cont]); |
| 477 return new If(condition, thenStatement, elseStatement); | 481 return new If( |
| 482 condition, thenStatement, elseStatement, node.sourceInformation); |
| 478 } | 483 } |
| 479 | 484 |
| 480 | 485 |
| 481 /************************** PRIMITIVES **************************/ | 486 /************************** PRIMITIVES **************************/ |
| 482 // | 487 // |
| 483 // Visit methods for primitives must return an expression. | 488 // Visit methods for primitives must return an expression. |
| 484 // | 489 // |
| 485 | 490 |
| 486 Expression visitSetField(cps_ir.SetField node) { | 491 Expression visitSetField(cps_ir.SetField node) { |
| 487 return new SetField(getVariableUse(node.objectRef), | 492 return new SetField(getVariableUse(node.objectRef), |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 return new SetStatic( | 584 return new SetStatic( |
| 580 node.element, | 585 node.element, |
| 581 getVariableUse(node.valueRef), | 586 getVariableUse(node.valueRef), |
| 582 node.sourceInformation); | 587 node.sourceInformation); |
| 583 } | 588 } |
| 584 | 589 |
| 585 Expression visitApplyBuiltinOperator(cps_ir.ApplyBuiltinOperator node) { | 590 Expression visitApplyBuiltinOperator(cps_ir.ApplyBuiltinOperator node) { |
| 586 if (node.operator == BuiltinOperator.IsFalsy) { | 591 if (node.operator == BuiltinOperator.IsFalsy) { |
| 587 return new Not(getVariableUse(node.argumentRefs.single)); | 592 return new Not(getVariableUse(node.argumentRefs.single)); |
| 588 } | 593 } |
| 589 return new ApplyBuiltinOperator(node.operator, | 594 return new ApplyBuiltinOperator( |
| 590 translateArguments(node.argumentRefs)); | 595 node.operator, |
| 596 translateArguments(node.argumentRefs), |
| 597 node.sourceInformation); |
| 591 } | 598 } |
| 592 | 599 |
| 593 Expression visitApplyBuiltinMethod(cps_ir.ApplyBuiltinMethod node) { | 600 Expression visitApplyBuiltinMethod(cps_ir.ApplyBuiltinMethod node) { |
| 594 return new ApplyBuiltinMethod(node.method, | 601 return new ApplyBuiltinMethod(node.method, |
| 595 getVariableUse(node.receiverRef), | 602 getVariableUse(node.receiverRef), |
| 596 translateArguments(node.argumentRefs), | 603 translateArguments(node.argumentRefs), |
| 597 receiverIsNotNull: !node.receiver.type.isNullable); | 604 receiverIsNotNull: !node.receiver.type.isNullable); |
| 598 } | 605 } |
| 599 | 606 |
| 600 Expression visitGetLength(cps_ir.GetLength node) { | 607 Expression visitGetLength(cps_ir.GetLength node) { |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 789 | 796 |
| 790 visitFunctionDefinition(cps_ir.FunctionDefinition node) { | 797 visitFunctionDefinition(cps_ir.FunctionDefinition node) { |
| 791 unexpectedNode(node); | 798 unexpectedNode(node); |
| 792 } | 799 } |
| 793 visitParameter(cps_ir.Parameter node) => unexpectedNode(node); | 800 visitParameter(cps_ir.Parameter node) => unexpectedNode(node); |
| 794 visitContinuation(cps_ir.Continuation node) => unexpectedNode(node); | 801 visitContinuation(cps_ir.Continuation node) => unexpectedNode(node); |
| 795 visitMutableVariable(cps_ir.MutableVariable node) => unexpectedNode(node); | 802 visitMutableVariable(cps_ir.MutableVariable node) => unexpectedNode(node); |
| 796 visitRethrow(cps_ir.Rethrow node) => unexpectedNode(node); | 803 visitRethrow(cps_ir.Rethrow node) => unexpectedNode(node); |
| 797 visitBoundsCheck(cps_ir.BoundsCheck node) => unexpectedNode(node); | 804 visitBoundsCheck(cps_ir.BoundsCheck node) => unexpectedNode(node); |
| 798 } | 805 } |
| OLD | NEW |