| 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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 /// A stack of singly-used labels that can be safely inlined at their use | 60 /// A stack of singly-used labels that can be safely inlined at their use |
| 61 /// site. | 61 /// site. |
| 62 /// | 62 /// |
| 63 /// Code for continuations with exactly one use is inlined at the use site. | 63 /// Code for continuations with exactly one use is inlined at the use site. |
| 64 /// This is not safe if the code is moved inside the scope of an exception | 64 /// This is not safe if the code is moved inside the scope of an exception |
| 65 /// handler (i.e., into a try block). We keep a stack of singly-referenced | 65 /// handler (i.e., into a try block). We keep a stack of singly-referenced |
| 66 /// continuations that are in scope without crossing a binding for a handler. | 66 /// continuations that are in scope without crossing a binding for a handler. |
| 67 List<cps_ir.Continuation> safeForInlining = <cps_ir.Continuation>[]; | 67 List<cps_ir.Continuation> safeForInlining = <cps_ir.Continuation>[]; |
| 68 | 68 |
| 69 ExecutableElement currentElement; | 69 ExecutableElement currentElement; |
| 70 cps_ir.Parameter thisParameter; |
| 70 cps_ir.Continuation returnContinuation; | 71 cps_ir.Continuation returnContinuation; |
| 71 | 72 |
| 72 Builder parent; | 73 Builder parent; |
| 73 | 74 |
| 74 Builder(this.internalError, [this.parent]); | 75 Builder(this.internalError, [this.parent]); |
| 75 | 76 |
| 76 Builder createInnerBuilder() { | 77 Builder createInnerBuilder() { |
| 77 return new Builder(internalError, this); | 78 return new Builder(internalError, this); |
| 78 } | 79 } |
| 79 | 80 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 while (variables.length <= primitive.registerIndex) { | 114 while (variables.length <= primitive.registerIndex) { |
| 114 variables.add(new Variable(currentElement, primitive.hint)); | 115 variables.add(new Variable(currentElement, primitive.hint)); |
| 115 } | 116 } |
| 116 return variables[primitive.registerIndex]; | 117 return variables[primitive.registerIndex]; |
| 117 } | 118 } |
| 118 | 119 |
| 119 /// Obtains a reference to the tree Variable corresponding to the IR primitive | 120 /// Obtains a reference to the tree Variable corresponding to the IR primitive |
| 120 /// referred to by [reference]. | 121 /// referred to by [reference]. |
| 121 /// This increments the reference count for the given variable, so the | 122 /// This increments the reference count for the given variable, so the |
| 122 /// returned expression must be used in the tree. | 123 /// returned expression must be used in the tree. |
| 123 VariableUse getVariableUse(cps_ir.Reference<cps_ir.Primitive> reference) { | 124 Expression getVariableUse(cps_ir.Reference<cps_ir.Primitive> reference) { |
| 125 if (reference.definition == thisParameter) { |
| 126 return new This(); |
| 127 } |
| 124 Variable variable = getVariable(reference.definition); | 128 Variable variable = getVariable(reference.definition); |
| 125 if (variable == null) { | 129 if (variable == null) { |
| 126 // Note: this may fail because you forgot to implement a visit-function | 130 // Note: this may fail because you forgot to implement a visit-function |
| 127 // in the RegisterAllocator. | 131 // in the RegisterAllocator. |
| 128 internalError( | 132 internalError( |
| 129 CURRENT_ELEMENT_SPANNABLE, | 133 CURRENT_ELEMENT_SPANNABLE, |
| 130 "Reference to ${reference.definition} has no register"); | 134 "Reference to ${reference.definition} has no register"); |
| 131 } | 135 } |
| 132 return new VariableUse(variable); | 136 return new VariableUse(variable); |
| 133 } | 137 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 163 Variable addFunctionParameter(cps_ir.Definition variable) { | 167 Variable addFunctionParameter(cps_ir.Definition variable) { |
| 164 if (variable is cps_ir.Parameter) { | 168 if (variable is cps_ir.Parameter) { |
| 165 return getVariable(variable); | 169 return getVariable(variable); |
| 166 } else { | 170 } else { |
| 167 return addMutableVariable(variable as cps_ir.MutableVariable); | 171 return addMutableVariable(variable as cps_ir.MutableVariable); |
| 168 } | 172 } |
| 169 } | 173 } |
| 170 | 174 |
| 171 FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) { | 175 FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) { |
| 172 currentElement = node.element; | 176 currentElement = node.element; |
| 177 thisParameter = node.thisParameter; |
| 173 List<Variable> parameters = | 178 List<Variable> parameters = |
| 174 node.parameters.map(addFunctionParameter).toList(); | 179 node.parameters.map(addFunctionParameter).toList(); |
| 175 Statement body; | 180 Statement body; |
| 176 if (!node.isAbstract) { | 181 if (!node.isAbstract) { |
| 177 returnContinuation = node.body.returnContinuation; | 182 returnContinuation = node.body.returnContinuation; |
| 178 phiTempVar = new Variable(node.element, null); | 183 phiTempVar = new Variable(node.element, null); |
| 179 body = visit(node.body); | 184 body = visit(node.body); |
| 180 } | 185 } |
| 181 | 186 |
| 182 return new FunctionDefinition(node.element, parameters, | 187 return new FunctionDefinition(node.element, parameters, |
| 183 body, node.localConstants, node.defaultParameterValues); | 188 body, node.localConstants, node.defaultParameterValues); |
| 184 } | 189 } |
| 185 | 190 |
| 186 ConstructorDefinition buildConstructor(cps_ir.ConstructorDefinition node) { | 191 ConstructorDefinition buildConstructor(cps_ir.ConstructorDefinition node) { |
| 187 currentElement = node.element; | 192 currentElement = node.element; |
| 193 thisParameter = node.thisParameter; |
| 188 List<Variable> parameters = | 194 List<Variable> parameters = |
| 189 node.parameters.map(addFunctionParameter).toList(); | 195 node.parameters.map(addFunctionParameter).toList(); |
| 190 List<Initializer> initializers; | 196 List<Initializer> initializers; |
| 191 Statement body; | 197 Statement body; |
| 192 if (!node.isAbstract) { | 198 if (!node.isAbstract) { |
| 193 initializers = node.initializers.map(visit).toList(); | 199 initializers = node.initializers.map(visit).toList(); |
| 194 returnContinuation = node.body.returnContinuation; | 200 returnContinuation = node.body.returnContinuation; |
| 195 | 201 |
| 196 phiTempVar = new Variable(node.element, null); | 202 phiTempVar = new Variable(node.element, null); |
| 197 body = visit(node.body); | 203 body = visit(node.body); |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 568 assert(cont.parameters.isEmpty); | 574 assert(cont.parameters.isEmpty); |
| 569 elseStatement = | 575 elseStatement = |
| 570 cont.hasExactlyOneUse ? visit(cont.body) : new Break(labels[cont]); | 576 cont.hasExactlyOneUse ? visit(cont.body) : new Break(labels[cont]); |
| 571 return new If(condition, thenStatement, elseStatement); | 577 return new If(condition, thenStatement, elseStatement); |
| 572 } | 578 } |
| 573 | 579 |
| 574 Expression visitConstant(cps_ir.Constant node) { | 580 Expression visitConstant(cps_ir.Constant node) { |
| 575 return new Constant(node.expression); | 581 return new Constant(node.expression); |
| 576 } | 582 } |
| 577 | 583 |
| 578 Expression visitThis(cps_ir.This node) { | |
| 579 return new This(); | |
| 580 } | |
| 581 | |
| 582 Expression visitReifyTypeVar(cps_ir.ReifyTypeVar node) { | 584 Expression visitReifyTypeVar(cps_ir.ReifyTypeVar node) { |
| 583 return new ReifyTypeVar(node.typeVariable); | 585 return new ReifyTypeVar(node.typeVariable); |
| 584 } | 586 } |
| 585 | 587 |
| 586 Expression visitLiteralList(cps_ir.LiteralList node) { | 588 Expression visitLiteralList(cps_ir.LiteralList node) { |
| 587 return new LiteralList( | 589 return new LiteralList( |
| 588 node.type, | 590 node.type, |
| 589 translateArguments(node.values)); | 591 translateArguments(node.values)); |
| 590 } | 592 } |
| 591 | 593 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 640 } | 642 } |
| 641 | 643 |
| 642 Expression visitReifyRuntimeType(cps_ir.ReifyRuntimeType node) { | 644 Expression visitReifyRuntimeType(cps_ir.ReifyRuntimeType node) { |
| 643 return new ReifyRuntimeType(getVariableUse(node.value)); | 645 return new ReifyRuntimeType(getVariableUse(node.value)); |
| 644 } | 646 } |
| 645 | 647 |
| 646 Expression visitReadTypeVariable(cps_ir.ReadTypeVariable node) { | 648 Expression visitReadTypeVariable(cps_ir.ReadTypeVariable node) { |
| 647 return new ReadTypeVariable(node.variable, getVariableUse(node.target)); | 649 return new ReadTypeVariable(node.variable, getVariableUse(node.target)); |
| 648 } | 650 } |
| 649 } | 651 } |
| OLD | NEW |