| 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 code_generator; | 5 library code_generator; |
| 6 | 6 |
| 7 import 'glue.dart'; | 7 import 'glue.dart'; |
| 8 | 8 |
| 9 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir; | 9 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir; |
| 10 import '../../js/js.dart' as js; | 10 import '../../js/js.dart' as js; |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 return js.propertyCall(interceptorLibrary, selector.name, arguments); | 233 return js.propertyCall(interceptorLibrary, selector.name, arguments); |
| 234 } else { | 234 } else { |
| 235 js.Expression elementAccess = glue.staticFunctionAccess(target); | 235 js.Expression elementAccess = glue.staticFunctionAccess(target); |
| 236 return new js.Call(elementAccess, arguments, | 236 return new js.Call(elementAccess, arguments, |
| 237 sourceInformation: sourceInformation); | 237 sourceInformation: sourceInformation); |
| 238 } | 238 } |
| 239 } | 239 } |
| 240 | 240 |
| 241 @override | 241 @override |
| 242 js.Expression visitInvokeConstructor(tree_ir.InvokeConstructor node) { | 242 js.Expression visitInvokeConstructor(tree_ir.InvokeConstructor node) { |
| 243 checkStaticTargetIsValid(node, node.target); | |
| 244 if (node.constant != null) return giveup(node); | 243 if (node.constant != null) return giveup(node); |
| 245 | 244 |
| 246 registry.registerInstantiatedType(node.type); | 245 registry.registerInstantiatedType(node.type); |
| 247 Selector selector = node.selector; | 246 Selector selector = node.selector; |
| 248 FunctionElement target = node.target; | 247 FunctionElement target = node.target; |
| 249 List<js.Expression> arguments = visitArguments(node.arguments); | 248 List<js.Expression> arguments = visitArguments(node.arguments); |
| 250 return buildStaticInvoke(selector, target, arguments); | 249 return buildStaticInvoke(selector, target, arguments); |
| 251 } | 250 } |
| 252 | 251 |
| 253 void registerMethodInvoke(tree_ir.InvokeMethod node) { | 252 void registerMethodInvoke(tree_ir.InvokeMethod node) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 269 } | 268 } |
| 270 | 269 |
| 271 @override | 270 @override |
| 272 js.Expression visitInvokeMethod(tree_ir.InvokeMethod node) { | 271 js.Expression visitInvokeMethod(tree_ir.InvokeMethod node) { |
| 273 registerMethodInvoke(node); | 272 registerMethodInvoke(node); |
| 274 return js.propertyCall(visitExpression(node.receiver), | 273 return js.propertyCall(visitExpression(node.receiver), |
| 275 glue.invocationName(node.selector), | 274 glue.invocationName(node.selector), |
| 276 visitArguments(node.arguments)); | 275 visitArguments(node.arguments)); |
| 277 } | 276 } |
| 278 | 277 |
| 279 /// Checks that the target of the static call is not an [ErroneousElement]. | |
| 280 /// | |
| 281 /// This helper should be removed and the code to generate the CPS IR for | |
| 282 /// the dart2js backend should construct a call to a helper that throw an | |
| 283 /// appropriate error message instead of the static call. | |
| 284 /// | |
| 285 /// See [SsaBuilder.visitStaticSend] as an example how to do this. | |
| 286 void checkStaticTargetIsValid(tree_ir.Node node, Element target) { | |
| 287 if (target.isErroneous) { | |
| 288 giveup(node, 'cannot generate error handling code' | |
| 289 ' for call to unresolved target'); | |
| 290 } | |
| 291 } | |
| 292 | |
| 293 @override | 278 @override |
| 294 js.Expression visitInvokeStatic(tree_ir.InvokeStatic node) { | 279 js.Expression visitInvokeStatic(tree_ir.InvokeStatic node) { |
| 295 checkStaticTargetIsValid(node, node.target); | |
| 296 Selector selector = node.selector; | 280 Selector selector = node.selector; |
| 297 if (node.target is FunctionElement) { | 281 assert(selector.isGetter || selector.isSetter || selector.isCall); |
| 298 assert(selector.isGetter || selector.isSetter || selector.isCall); | 282 FunctionElement target = node.target; |
| 299 FunctionElement target = node.target; | 283 List<js.Expression> arguments = visitArguments(node.arguments); |
| 300 List<js.Expression> arguments = visitArguments(node.arguments); | 284 return buildStaticInvoke(selector, target, arguments, |
| 301 return buildStaticInvoke(selector, target, arguments, | 285 sourceInformation: node.sourceInformation); |
| 302 sourceInformation: node.sourceInformation); | |
| 303 } else { | |
| 304 assert(selector.isGetter || selector.isSetter); | |
| 305 FieldElement target = node.target; | |
| 306 registry.registerStaticUse(target); | |
| 307 js.Expression field = glue.staticFieldAccess(target); | |
| 308 if (selector.isGetter) { | |
| 309 assert(node.arguments.isEmpty); | |
| 310 return field; | |
| 311 } else { | |
| 312 assert(node.arguments.length == 1); | |
| 313 js.Expression value = visitExpression(node.arguments.first); | |
| 314 return new js.Assignment(field, value); | |
| 315 } | |
| 316 } | |
| 317 } | 286 } |
| 318 | 287 |
| 319 @override | 288 @override |
| 320 js.Expression visitInvokeMethodDirectly(tree_ir.InvokeMethodDirectly node) { | 289 js.Expression visitInvokeMethodDirectly(tree_ir.InvokeMethodDirectly node) { |
| 321 registry.registerDirectInvocation(node.target.declaration); | 290 registry.registerDirectInvocation(node.target.declaration); |
| 322 if (node.target is ConstructorBodyElement) { | 291 if (node.target is ConstructorBodyElement) { |
| 323 // A constructor body cannot be overriden or intercepted, so we can | 292 // A constructor body cannot be overriden or intercepted, so we can |
| 324 // use the short form for this invocation. | 293 // use the short form for this invocation. |
| 325 return js.js('#.#(#)', | 294 return js.js('#.#(#)', |
| 326 [visitExpression(node.receiver), | 295 [visitExpression(node.receiver), |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 | 580 |
| 612 @override | 581 @override |
| 613 js.Assignment visitSetField(tree_ir.SetField node) { | 582 js.Assignment visitSetField(tree_ir.SetField node) { |
| 614 js.PropertyAccess field = | 583 js.PropertyAccess field = |
| 615 new js.PropertyAccess.field( | 584 new js.PropertyAccess.field( |
| 616 visitExpression(node.object), | 585 visitExpression(node.object), |
| 617 glue.instanceFieldPropertyName(node.field)); | 586 glue.instanceFieldPropertyName(node.field)); |
| 618 return new js.Assignment(field, visitExpression(node.value)); | 587 return new js.Assignment(field, visitExpression(node.value)); |
| 619 } | 588 } |
| 620 | 589 |
| 590 @override |
| 591 js.Expression visitGetStatic(tree_ir.GetStatic node) { |
| 592 assert(node.element is FieldElement || node.element is FunctionElement); |
| 593 if (node.element is FieldElement) { |
| 594 registry.registerStaticUse(node.element.declaration); |
| 595 return glue.staticFieldAccess(node.element); |
| 596 } else { |
| 597 registry.registerGetOfStaticFunction(node.element.declaration); |
| 598 return glue.isolateStaticClosureAccess(node.element); |
| 599 } |
| 600 } |
| 601 |
| 602 @override |
| 603 js.Expression visitSetStatic(tree_ir.SetStatic node) { |
| 604 assert(node.element is FieldElement); |
| 605 registry.registerStaticUse(node.element.declaration); |
| 606 js.Expression field = glue.staticFieldAccess(node.element); |
| 607 js.Expression value = visitExpression(node.value); |
| 608 return new js.Assignment(field, value); |
| 609 } |
| 610 |
| 621 js.Expression buildStaticHelperInvocation(FunctionElement helper, | 611 js.Expression buildStaticHelperInvocation(FunctionElement helper, |
| 622 List<js.Expression> arguments) { | 612 List<js.Expression> arguments) { |
| 623 registry.registerStaticUse(helper); | 613 registry.registerStaticUse(helper); |
| 624 return buildStaticInvoke(new Selector.fromElement(helper), helper, | 614 return buildStaticInvoke(new Selector.fromElement(helper), helper, |
| 625 arguments); | 615 arguments); |
| 626 } | 616 } |
| 627 | 617 |
| 628 @override | 618 @override |
| 629 js.Expression visitReifyRuntimeType(tree_ir.ReifyRuntimeType node) { | 619 js.Expression visitReifyRuntimeType(tree_ir.ReifyRuntimeType node) { |
| 630 FunctionElement createType = glue.getCreateRuntimeType(); | 620 FunctionElement createType = glue.getCreateRuntimeType(); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 676 | 666 |
| 677 @override | 667 @override |
| 678 visitVariableDeclaration(tree_ir.VariableDeclaration node) { | 668 visitVariableDeclaration(tree_ir.VariableDeclaration node) { |
| 679 return errorUnsupportedNode(node); | 669 return errorUnsupportedNode(node); |
| 680 } | 670 } |
| 681 | 671 |
| 682 errorUnsupportedNode(tree_ir.DartSpecificNode node) { | 672 errorUnsupportedNode(tree_ir.DartSpecificNode node) { |
| 683 throw "Unsupported node in JS backend: $node"; | 673 throw "Unsupported node in JS backend: $node"; |
| 684 } | 674 } |
| 685 } | 675 } |
| OLD | NEW |