| 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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 compiler.currentElement, | 105 compiler.currentElement, |
| 106 "Reference to ${reference.definition} has no register"); | 106 "Reference to ${reference.definition} has no register"); |
| 107 } | 107 } |
| 108 ++variable.readCount; | 108 ++variable.readCount; |
| 109 return variable; | 109 return variable; |
| 110 } | 110 } |
| 111 | 111 |
| 112 ExecutableDefinition build(cps_ir.ExecutableDefinition node) { | 112 ExecutableDefinition build(cps_ir.ExecutableDefinition node) { |
| 113 if (node is cps_ir.FieldDefinition) { | 113 if (node is cps_ir.FieldDefinition) { |
| 114 return buildField(node); | 114 return buildField(node); |
| 115 } else if (node is cps_ir.ConstructorDefinition) { |
| 116 return buildConstructor(node); |
| 115 } else if (node is cps_ir.FunctionDefinition) { | 117 } else if (node is cps_ir.FunctionDefinition) { |
| 116 return buildFunction(node); | 118 return buildFunction(node); |
| 117 } | 119 } |
| 118 assert(false); | 120 assert(false); |
| 121 return null; |
| 119 } | 122 } |
| 120 | 123 |
| 121 FieldDefinition buildField(cps_ir.FieldDefinition node) { | 124 FieldDefinition buildField(cps_ir.FieldDefinition node) { |
| 122 Statement body; | 125 Statement body; |
| 123 if (node.hasInitializer) { | 126 if (node.hasInitializer) { |
| 124 currentElement = node.element; | 127 currentElement = node.element; |
| 125 returnContinuation = node.returnContinuation; | 128 returnContinuation = node.body.returnContinuation; |
| 126 | 129 |
| 127 phiTempVar = new Variable(node.element, null); | 130 phiTempVar = new Variable(node.element, null); |
| 128 | 131 |
| 129 body = visit(node.body); | 132 body = visit(node.body); |
| 130 } | 133 } |
| 131 return new FieldDefinition(node.element, body); | 134 return new FieldDefinition(node.element, body); |
| 132 } | 135 } |
| 133 | 136 |
| 134 Variable getFunctionParameter(cps_ir.Definition variable) { | 137 Variable getFunctionParameter(cps_ir.Definition variable) { |
| 135 if (variable is cps_ir.Parameter) { | 138 if (variable is cps_ir.Parameter) { |
| 136 return getVariable(variable); | 139 return getVariable(variable); |
| 137 } else { | 140 } else { |
| 138 return getClosureVariable(variable as cps_ir.ClosureVariable); | 141 return getClosureVariable(variable as cps_ir.ClosureVariable); |
| 139 } | 142 } |
| 140 } | 143 } |
| 141 | 144 |
| 142 FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) { | 145 FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) { |
| 143 currentElement = node.element; | 146 currentElement = node.element; |
| 144 List<Variable> parameters = <Variable>[]; | 147 List<Variable> parameters = <Variable>[]; |
| 145 for (cps_ir.Definition p in node.parameters) { | 148 for (cps_ir.Definition p in node.parameters) { |
| 146 Variable parameter = getFunctionParameter(p); | 149 Variable parameter = getFunctionParameter(p); |
| 147 assert(parameter != null); | 150 assert(parameter != null); |
| 148 ++parameter.writeCount; // Being a parameter counts as a write. | 151 ++parameter.writeCount; // Being a parameter counts as a write. |
| 149 parameters.add(parameter); | 152 parameters.add(parameter); |
| 150 } | 153 } |
| 151 returnContinuation = node.returnContinuation; | |
| 152 | 154 |
| 153 Statement body; | 155 Statement body; |
| 154 if (!node.isAbstract) { | 156 if (!node.isAbstract) { |
| 157 returnContinuation = node.body.returnContinuation; |
| 155 phiTempVar = new Variable(node.element, null); | 158 phiTempVar = new Variable(node.element, null); |
| 156 body = visit(node.body); | 159 body = visit(node.body); |
| 157 } | 160 } |
| 158 | 161 |
| 159 return new FunctionDefinition(node.element, parameters, | 162 return new FunctionDefinition(node.element, parameters, |
| 160 body, node.localConstants, node.defaultParameterValues); | 163 body, node.localConstants, node.defaultParameterValues); |
| 161 } | 164 } |
| 162 | 165 |
| 166 ConstructorDefinition buildConstructor(cps_ir.ConstructorDefinition node) { |
| 167 currentElement = node.element; |
| 168 List<Variable> parameters = <Variable>[]; |
| 169 for (cps_ir.Definition p in node.parameters) { |
| 170 Variable parameter = getFunctionParameter(p); |
| 171 assert(parameter != null); |
| 172 ++parameter.writeCount; // Being a parameter counts as a write. |
| 173 parameters.add(parameter); |
| 174 } |
| 175 List<Initializer> initializers; |
| 176 Statement body; |
| 177 if (!node.isAbstract) { |
| 178 initializers = node.initializers.map(visit).toList(); |
| 179 returnContinuation = node.body.returnContinuation; |
| 180 |
| 181 phiTempVar = new Variable(node.element, null); |
| 182 body = visit(node.body); |
| 183 } |
| 184 |
| 185 return new ConstructorDefinition(node.element, parameters, |
| 186 body, initializers, node.localConstants, node.defaultParameterValues, |
| 187 node.isConst); |
| 188 } |
| 189 |
| 190 |
| 163 List<Expression> translateArguments(List<cps_ir.Reference> args) { | 191 List<Expression> translateArguments(List<cps_ir.Reference> args) { |
| 164 return new List<Expression>.generate(args.length, | 192 return new List<Expression>.generate(args.length, |
| 165 (int index) => getVariableReference(args[index])); | 193 (int index) => getVariableReference(args[index])); |
| 166 } | 194 } |
| 167 | 195 |
| 168 List<Variable> translatePhiArguments(List<cps_ir.Reference> args) { | 196 List<Variable> translatePhiArguments(List<cps_ir.Reference> args) { |
| 169 return new List<Variable>.generate(args.length, | 197 return new List<Variable>.generate(args.length, |
| 170 (int index) => getVariableReference(args[index])); | 198 (int index) => getVariableReference(args[index])); |
| 171 } | 199 } |
| 172 | 200 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 if (first == null) { | 292 if (first == null) { |
| 265 first = buildRest(); | 293 first = buildRest(); |
| 266 } else { | 294 } else { |
| 267 current.next = buildRest(); | 295 current.next = buildRest(); |
| 268 } | 296 } |
| 269 return first; | 297 return first; |
| 270 } | 298 } |
| 271 | 299 |
| 272 visitNode(cps_ir.Node node) => throw "Unhandled node: $node"; | 300 visitNode(cps_ir.Node node) => throw "Unhandled node: $node"; |
| 273 | 301 |
| 302 Initializer visitFieldInitializer(cps_ir.FieldInitializer node) { |
| 303 returnContinuation = node.body.returnContinuation; |
| 304 return new FieldInitializer(node.element, visit(node.body.body)); |
| 305 } |
| 306 |
| 307 Initializer visitSuperInitializer(cps_ir.SuperInitializer node) { |
| 308 List<Statement> arguments = |
| 309 node.arguments.map((cps_ir.RunnableBody argument) { |
| 310 returnContinuation = argument.returnContinuation; |
| 311 return visit(argument.body); |
| 312 }).toList(); |
| 313 return new SuperInitializer(node.target, node.selector, arguments); |
| 314 } |
| 315 |
| 274 Statement visitLetPrim(cps_ir.LetPrim node) { | 316 Statement visitLetPrim(cps_ir.LetPrim node) { |
| 275 Variable variable = getVariable(node.primitive); | 317 Variable variable = getVariable(node.primitive); |
| 276 | 318 |
| 277 // Don't translate unused primitives. | 319 // Don't translate unused primitives. |
| 278 if (variable == null) return visit(node.body); | 320 if (variable == null) return visit(node.body); |
| 279 | 321 |
| 280 Node definition = visit(node.primitive); | 322 Node definition = visit(node.primitive); |
| 281 | 323 |
| 282 // visitPrimitive returns a Statement without successor if it cannot occur | 324 // visitPrimitive returns a Statement without successor if it cannot occur |
| 283 // in expression context (currently only the case for FunctionDeclarations). | 325 // in expression context (currently only the case for FunctionDeclarations). |
| 284 if (definition is Statement) { | 326 if (definition is Statement) { |
| 285 definition.next = visit(node.body); | 327 definition.next = visit(node.body); |
| 286 return definition; | 328 return definition; |
| 287 } else { | 329 } else { |
| 288 return new Assign(variable, definition, visit(node.body)); | 330 return new Assign(variable, definition, visit(node.body)); |
| 289 } | 331 } |
| 290 } | 332 } |
| 291 | 333 |
| 334 Statement visitRunnableBody(cps_ir.RunnableBody node) { |
| 335 return visit(node.body); |
| 336 } |
| 337 |
| 292 Statement visitLetCont(cps_ir.LetCont node) { | 338 Statement visitLetCont(cps_ir.LetCont node) { |
| 293 Label label; | 339 Label label; |
| 294 if (node.continuation.hasMultipleUses) { | 340 if (node.continuation.hasMultipleUses) { |
| 295 label = new Label(); | 341 label = new Label(); |
| 296 labels[node.continuation] = label; | 342 labels[node.continuation] = label; |
| 297 } | 343 } |
| 298 Statement body = visit(node.body); | 344 Statement body = visit(node.body); |
| 299 // The continuation's body is not always translated directly here because | 345 // The continuation's body is not always translated directly here because |
| 300 // it may have been already translated: | 346 // it may have been already translated: |
| 301 // * For singly-used continuations, the continuation's body is | 347 // * For singly-used continuations, the continuation's body is |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 501 | 547 |
| 502 Expression visitIdentical(cps_ir.Identical node) { | 548 Expression visitIdentical(cps_ir.Identical node) { |
| 503 return new InvokeStatic( | 549 return new InvokeStatic( |
| 504 compiler.identicalFunction, | 550 compiler.identicalFunction, |
| 505 identicalSelector, | 551 identicalSelector, |
| 506 <Expression>[getVariableReference(node.left), | 552 <Expression>[getVariableReference(node.left), |
| 507 getVariableReference(node.right)]); | 553 getVariableReference(node.right)]); |
| 508 } | 554 } |
| 509 } | 555 } |
| 510 | 556 |
| OLD | NEW |