| 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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 /// referred to by [reference]. | 113 /// referred to by [reference]. |
| 114 /// This increments the reference count for the given variable, so the | 114 /// This increments the reference count for the given variable, so the |
| 115 /// returned expression must be used in the tree. | 115 /// returned expression must be used in the tree. |
| 116 Expression getVariableUse(cps_ir.Reference<cps_ir.Primitive> reference) { | 116 Expression getVariableUse(cps_ir.Reference<cps_ir.Primitive> reference) { |
| 117 if (thisParameter != null && reference.definition == thisParameter) { | 117 if (thisParameter != null && reference.definition == thisParameter) { |
| 118 return new This(); | 118 return new This(); |
| 119 } | 119 } |
| 120 return new VariableUse(getVariable(reference.definition)); | 120 return new VariableUse(getVariable(reference.definition)); |
| 121 } | 121 } |
| 122 | 122 |
| 123 ExecutableDefinition build(cps_ir.ExecutableDefinition node) { | 123 RootNode build(cps_ir.RootNode node) { |
| 124 // TODO(asgerf): Don't have build AND buildXXX as public API. | 124 // TODO(asgerf): Don't have build AND buildXXX as public API. |
| 125 if (node is cps_ir.FieldDefinition) { | 125 if (node is cps_ir.FieldDefinition) { |
| 126 return buildField(node); | 126 return buildField(node); |
| 127 } else if (node is cps_ir.ConstructorDefinition) { | 127 } else if (node is cps_ir.ConstructorDefinition) { |
| 128 return buildConstructor(node); | 128 return buildConstructor(node); |
| 129 } else { | 129 } else { |
| 130 assert(dart2js.invariant( | 130 assert(dart2js.invariant( |
| 131 CURRENT_ELEMENT_SPANNABLE, | 131 CURRENT_ELEMENT_SPANNABLE, |
| 132 node is cps_ir.FunctionDefinition, | 132 node is cps_ir.FunctionDefinition, |
| 133 message: 'expected FunctionDefinition or FieldDefinition, ' | 133 message: 'expected FunctionDefinition or FieldDefinition, ' |
| 134 ' found $node')); | 134 ' found $node')); |
| 135 return buildFunction(node); | 135 return buildFunction(node); |
| 136 } | 136 } |
| 137 } | 137 } |
| 138 | 138 |
| 139 FieldDefinition buildField(cps_ir.FieldDefinition node) { | 139 FieldDefinition buildField(cps_ir.FieldDefinition node) { |
| 140 Statement body; | 140 Statement body; |
| 141 if (node.hasInitializer) { | 141 if (!node.isEmpty) { |
| 142 currentElement = node.element; | 142 currentElement = node.element; |
| 143 returnContinuation = node.body.returnContinuation; | 143 returnContinuation = node.body.returnContinuation; |
| 144 | 144 |
| 145 phiTempVar = new Variable(node.element, null); | 145 phiTempVar = new Variable(node.element, null); |
| 146 | 146 |
| 147 body = visit(node.body); | 147 body = visit(node.body); |
| 148 } | 148 } |
| 149 return new FieldDefinition(node.element, body); | 149 return new FieldDefinition(node.element, body); |
| 150 } | 150 } |
| 151 | 151 |
| 152 Variable addFunctionParameter(cps_ir.Definition variable) { | 152 Variable addFunctionParameter(cps_ir.Definition variable) { |
| 153 if (variable is cps_ir.Parameter) { | 153 if (variable is cps_ir.Parameter) { |
| 154 return getVariable(variable); | 154 return getVariable(variable); |
| 155 } else { | 155 } else { |
| 156 return addMutableVariable(variable as cps_ir.MutableVariable); | 156 return addMutableVariable(variable as cps_ir.MutableVariable); |
| 157 } | 157 } |
| 158 } | 158 } |
| 159 | 159 |
| 160 FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) { | 160 FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) { |
| 161 currentElement = node.element; | 161 currentElement = node.element; |
| 162 if (parent != null) { | 162 if (parent != null) { |
| 163 // Local function's 'this' refers to enclosing method's 'this' | 163 // Local function's 'this' refers to enclosing method's 'this' |
| 164 thisParameter = parent.thisParameter; | 164 thisParameter = parent.thisParameter; |
| 165 } else { | 165 } else { |
| 166 thisParameter = node.thisParameter; | 166 thisParameter = node.thisParameter; |
| 167 } | 167 } |
| 168 List<Variable> parameters = | 168 List<Variable> parameters = |
| 169 node.parameters.map(addFunctionParameter).toList(); | 169 node.parameters.map(addFunctionParameter).toList(); |
| 170 Statement body; | 170 Statement body; |
| 171 if (!node.isAbstract) { | 171 if (!node.isEmpty) { |
| 172 returnContinuation = node.body.returnContinuation; | 172 returnContinuation = node.body.returnContinuation; |
| 173 phiTempVar = new Variable(node.element, null); | 173 phiTempVar = new Variable(node.element, null); |
| 174 body = visit(node.body); | 174 body = visit(node.body); |
| 175 } | 175 } |
| 176 | 176 |
| 177 return new FunctionDefinition(node.element, parameters, | 177 return new FunctionDefinition(node.element, parameters, |
| 178 body, node.localConstants, node.defaultParameterValues); | 178 body, node.localConstants, node.defaultParameterValues); |
| 179 } | 179 } |
| 180 | 180 |
| 181 ConstructorDefinition buildConstructor(cps_ir.ConstructorDefinition node) { | 181 ConstructorDefinition buildConstructor(cps_ir.ConstructorDefinition node) { |
| 182 currentElement = node.element; | 182 currentElement = node.element; |
| 183 thisParameter = node.thisParameter; | 183 thisParameter = node.thisParameter; |
| 184 List<Variable> parameters = | 184 List<Variable> parameters = |
| 185 node.parameters.map(addFunctionParameter).toList(); | 185 node.parameters.map(addFunctionParameter).toList(); |
| 186 List<Initializer> initializers; | 186 List<Initializer> initializers; |
| 187 Statement body; | 187 Statement body; |
| 188 if (!node.isAbstract) { | 188 if (!node.isEmpty) { |
| 189 initializers = node.initializers.map(visit).toList(); | 189 initializers = node.initializers.map(visit).toList(); |
| 190 returnContinuation = node.body.returnContinuation; | 190 returnContinuation = node.body.returnContinuation; |
| 191 | 191 |
| 192 phiTempVar = new Variable(node.element, null); | 192 phiTempVar = new Variable(node.element, null); |
| 193 body = visit(node.body); | 193 body = visit(node.body); |
| 194 } | 194 } |
| 195 | 195 |
| 196 return new ConstructorDefinition(node.element, parameters, | 196 return new ConstructorDefinition(node.element, parameters, |
| 197 body, initializers, node.localConstants, node.defaultParameterValues); | 197 body, initializers, node.localConstants, node.defaultParameterValues); |
| 198 } | 198 } |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 return unexpectedNode(node); | 343 return unexpectedNode(node); |
| 344 } | 344 } |
| 345 | 345 |
| 346 Initializer visitFieldInitializer(cps_ir.FieldInitializer node) { | 346 Initializer visitFieldInitializer(cps_ir.FieldInitializer node) { |
| 347 returnContinuation = node.body.returnContinuation; | 347 returnContinuation = node.body.returnContinuation; |
| 348 return new FieldInitializer(node.element, visit(node.body.body)); | 348 return new FieldInitializer(node.element, visit(node.body.body)); |
| 349 } | 349 } |
| 350 | 350 |
| 351 Initializer visitSuperInitializer(cps_ir.SuperInitializer node) { | 351 Initializer visitSuperInitializer(cps_ir.SuperInitializer node) { |
| 352 List<Statement> arguments = | 352 List<Statement> arguments = |
| 353 node.arguments.map((cps_ir.RunnableBody argument) { | 353 node.arguments.map((cps_ir.Body argument) { |
| 354 returnContinuation = argument.returnContinuation; | 354 returnContinuation = argument.returnContinuation; |
| 355 return visit(argument.body); | 355 return visit(argument.body); |
| 356 }).toList(); | 356 }).toList(); |
| 357 return new SuperInitializer(node.target, node.selector, arguments); | 357 return new SuperInitializer(node.target, node.selector, arguments); |
| 358 } | 358 } |
| 359 | 359 |
| 360 Statement visitLetPrim(cps_ir.LetPrim node) { | 360 Statement visitLetPrim(cps_ir.LetPrim node) { |
| 361 Variable variable = getVariable(node.primitive); | 361 Variable variable = getVariable(node.primitive); |
| 362 | 362 |
| 363 // Don't translate unused primitives. | 363 // Don't translate unused primitives. |
| 364 if (variable == null) return visit(node.body); | 364 if (variable == null) return visit(node.body); |
| 365 | 365 |
| 366 Node definition = visit(node.primitive); | 366 Node definition = visit(node.primitive); |
| 367 | 367 |
| 368 // visitPrimitive returns a Statement without successor if it cannot occur | 368 // visitPrimitive returns a Statement without successor if it cannot occur |
| 369 // in expression context (currently only the case for FunctionDeclarations). | 369 // in expression context (currently only the case for FunctionDeclarations). |
| 370 if (definition is Statement) { | 370 if (definition is Statement) { |
| 371 definition.next = visit(node.body); | 371 definition.next = visit(node.body); |
| 372 return definition; | 372 return definition; |
| 373 } else { | 373 } else { |
| 374 return new Assign(variable, definition, visit(node.body)); | 374 return new Assign(variable, definition, visit(node.body)); |
| 375 } | 375 } |
| 376 } | 376 } |
| 377 | 377 |
| 378 Statement visitRunnableBody(cps_ir.RunnableBody node) { | 378 Statement visitBody(cps_ir.Body node) { |
| 379 return visit(node.body); | 379 return visit(node.body); |
| 380 } | 380 } |
| 381 | 381 |
| 382 Statement visitLetCont(cps_ir.LetCont node) { | 382 Statement visitLetCont(cps_ir.LetCont node) { |
| 383 // Introduce labels for continuations that need them. | 383 // Introduce labels for continuations that need them. |
| 384 int safeForInliningLengthOnEntry = safeForInlining.length; | 384 int safeForInliningLengthOnEntry = safeForInlining.length; |
| 385 for (cps_ir.Continuation continuation in node.continuations) { | 385 for (cps_ir.Continuation continuation in node.continuations) { |
| 386 if (continuation.hasMultipleUses) { | 386 if (continuation.hasMultipleUses) { |
| 387 labels[continuation] = new Label(); | 387 labels[continuation] = new Label(); |
| 388 } else { | 388 } else { |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 640 } | 640 } |
| 641 | 641 |
| 642 @override | 642 @override |
| 643 Node visitTypeExpression(cps_ir.TypeExpression node) { | 643 Node visitTypeExpression(cps_ir.TypeExpression node) { |
| 644 return new TypeExpression( | 644 return new TypeExpression( |
| 645 node.dartType, | 645 node.dartType, |
| 646 node.arguments.map(getVariableUse).toList()); | 646 node.arguments.map(getVariableUse).toList()); |
| 647 } | 647 } |
| 648 } | 648 } |
| 649 | 649 |
| OLD | NEW |