| 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 '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../constants/values.dart'; | 8 import '../constants/values.dart'; |
| 9 import '../cps_ir/cps_ir_nodes.dart' as cps_ir; | 9 import '../cps_ir/cps_ir_nodes.dart' as cps_ir; |
| 10 import '../elements/elements.dart'; | 10 import '../elements/elements.dart'; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 | 91 |
| 92 VariableUse getMutableVariableUse( | 92 VariableUse getMutableVariableUse( |
| 93 cps_ir.Reference<cps_ir.MutableVariable> reference) { | 93 cps_ir.Reference<cps_ir.MutableVariable> reference) { |
| 94 Variable variable = getMutableVariable(reference.definition); | 94 Variable variable = getMutableVariable(reference.definition); |
| 95 return new VariableUse(variable); | 95 return new VariableUse(variable); |
| 96 } | 96 } |
| 97 | 97 |
| 98 /// Obtains the variable representing the given primitive. Returns null for | 98 /// Obtains the variable representing the given primitive. Returns null for |
| 99 /// primitives that have no reference and do not need a variable. | 99 /// primitives that have no reference and do not need a variable. |
| 100 Variable getVariable(cps_ir.Primitive primitive) { | 100 Variable getVariable(cps_ir.Primitive primitive) { |
| 101 primitive = primitive.effectiveDefinition; |
| 101 return primitive2variable.putIfAbsent(primitive, | 102 return primitive2variable.putIfAbsent(primitive, |
| 102 () => new Variable(currentElement, primitive.hint)); | 103 () => new Variable(currentElement, primitive.hint)); |
| 103 } | 104 } |
| 104 | 105 |
| 105 /// Obtains a reference to the tree Variable corresponding to the IR primitive | 106 /// Obtains a reference to the tree Variable corresponding to the IR primitive |
| 106 /// referred to by [reference]. | 107 /// referred to by [reference]. |
| 107 /// This increments the reference count for the given variable, so the | 108 /// This increments the reference count for the given variable, so the |
| 108 /// returned expression must be used in the tree. | 109 /// returned expression must be used in the tree. |
| 109 Expression getVariableUse(cps_ir.Reference<cps_ir.Primitive> reference) { | 110 Expression getVariableUse(cps_ir.Reference<cps_ir.Primitive> reference) { |
| 110 cps_ir.Primitive prim = reference.definition.effectiveDefinition; | 111 cps_ir.Primitive prim = reference.definition.effectiveDefinition; |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 Expression visitCreateInstance(cps_ir.CreateInstance node) { | 452 Expression visitCreateInstance(cps_ir.CreateInstance node) { |
| 452 return new CreateInstance( | 453 return new CreateInstance( |
| 453 node.classElement, | 454 node.classElement, |
| 454 translateArguments(node.arguments), | 455 translateArguments(node.arguments), |
| 455 translateArguments(node.typeInformation), | 456 translateArguments(node.typeInformation), |
| 456 node.sourceInformation); | 457 node.sourceInformation); |
| 457 } | 458 } |
| 458 | 459 |
| 459 Expression visitGetField(cps_ir.GetField node) { | 460 Expression visitGetField(cps_ir.GetField node) { |
| 460 return new GetField(getVariableUse(node.object), node.field, | 461 return new GetField(getVariableUse(node.object), node.field, |
| 461 objectIsNotNull: node.objectIsNotNull); | 462 objectIsNotNull: !node.object.definition.type.isNullable); |
| 462 } | 463 } |
| 463 | 464 |
| 464 Expression visitCreateBox(cps_ir.CreateBox node) { | 465 Expression visitCreateBox(cps_ir.CreateBox node) { |
| 465 return new CreateBox(); | 466 return new CreateBox(); |
| 466 } | 467 } |
| 467 | 468 |
| 468 Expression visitCreateInvocationMirror(cps_ir.CreateInvocationMirror node) { | 469 Expression visitCreateInvocationMirror(cps_ir.CreateInvocationMirror node) { |
| 469 return new CreateInvocationMirror( | 470 return new CreateInvocationMirror( |
| 470 node.selector, | 471 node.selector, |
| 471 translateArguments(node.arguments)); | 472 translateArguments(node.arguments)); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 return new Not(getVariableUse(node.arguments.single)); | 549 return new Not(getVariableUse(node.arguments.single)); |
| 549 } | 550 } |
| 550 return new ApplyBuiltinOperator(node.operator, | 551 return new ApplyBuiltinOperator(node.operator, |
| 551 translateArguments(node.arguments)); | 552 translateArguments(node.arguments)); |
| 552 } | 553 } |
| 553 | 554 |
| 554 Expression visitApplyBuiltinMethod(cps_ir.ApplyBuiltinMethod node) { | 555 Expression visitApplyBuiltinMethod(cps_ir.ApplyBuiltinMethod node) { |
| 555 return new ApplyBuiltinMethod(node.method, | 556 return new ApplyBuiltinMethod(node.method, |
| 556 getVariableUse(node.receiver), | 557 getVariableUse(node.receiver), |
| 557 translateArguments(node.arguments), | 558 translateArguments(node.arguments), |
| 558 receiverIsNotNull: node.receiverIsNotNull); | 559 receiverIsNotNull: !node.receiver.definition.type.isNullable); |
| 559 } | 560 } |
| 560 | 561 |
| 561 Expression visitGetLength(cps_ir.GetLength node) { | 562 Expression visitGetLength(cps_ir.GetLength node) { |
| 562 return new GetLength(getVariableUse(node.object)); | 563 return new GetLength(getVariableUse(node.object)); |
| 563 } | 564 } |
| 564 | 565 |
| 565 Expression visitGetIndex(cps_ir.GetIndex node) { | 566 Expression visitGetIndex(cps_ir.GetIndex node) { |
| 566 return new GetIndex(getVariableUse(node.object), | 567 return new GetIndex(getVariableUse(node.object), |
| 567 getVariableUse(node.index)); | 568 getVariableUse(node.index)); |
| 568 } | 569 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 579 node.sourceInformation); | 580 node.sourceInformation); |
| 580 } | 581 } |
| 581 | 582 |
| 582 Expression visitInvokeMethod(cps_ir.InvokeMethod node) { | 583 Expression visitInvokeMethod(cps_ir.InvokeMethod node) { |
| 583 InvokeMethod invoke = new InvokeMethod( | 584 InvokeMethod invoke = new InvokeMethod( |
| 584 getVariableUse(node.receiver), | 585 getVariableUse(node.receiver), |
| 585 node.selector, | 586 node.selector, |
| 586 node.mask, | 587 node.mask, |
| 587 translateArguments(node.arguments), | 588 translateArguments(node.arguments), |
| 588 node.sourceInformation); | 589 node.sourceInformation); |
| 589 invoke.receiverIsNotNull = node.receiverIsNotNull; | 590 // Sometimes we know the Dart receiver is non-null because it has been |
| 591 // refined, which implies that the JS receiver also can not be null at the |
| 592 // use-site. Interceptors are not refined, so this information is not |
| 593 // always available on the JS receiver. |
| 594 // Also check the JS receiver's type, however, because sometimes we know an |
| 595 // interceptor is non-null because it intercepts JSNull. |
| 596 invoke.receiverIsNotNull = |
| 597 !node.dartReceiver.type.isNullable || |
| 598 !node.receiver.definition.type.isNullable; |
| 590 return invoke; | 599 return invoke; |
| 591 } | 600 } |
| 592 | 601 |
| 593 Expression visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) { | 602 Expression visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) { |
| 594 Expression receiver = getVariableUse(node.receiver); | 603 Expression receiver = getVariableUse(node.receiver); |
| 595 List<Expression> arguments = translateArguments(node.arguments); | 604 List<Expression> arguments = translateArguments(node.arguments); |
| 596 return new InvokeMethodDirectly(receiver, node.target, | 605 return new InvokeMethodDirectly(receiver, node.target, |
| 597 node.selector, arguments, node.sourceInformation); | 606 node.selector, arguments, node.sourceInformation); |
| 598 } | 607 } |
| 599 | 608 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 666 return new Yield(getVariableUse(node.input), node.hasStar, next); | 675 return new Yield(getVariableUse(node.input), node.hasStar, next); |
| 667 }; | 676 }; |
| 668 } | 677 } |
| 669 | 678 |
| 670 @override | 679 @override |
| 671 Expression visitAwait(cps_ir.Await node) { | 680 Expression visitAwait(cps_ir.Await node) { |
| 672 return new Await(getVariableUse(node.input)); | 681 return new Await(getVariableUse(node.input)); |
| 673 } | 682 } |
| 674 | 683 |
| 675 @override | 684 @override |
| 676 Expression visitRefinement(cps_ir.Refinement node) { | 685 visitRefinement(cps_ir.Refinement node) { |
| 677 throw 'Unexpected Refinement node in tree builder'; | 686 return (Statement next) => next; // Compile to nothing. |
| 678 } | 687 } |
| 679 | 688 |
| 680 @override | 689 @override |
| 681 Expression visitBoundsCheck(cps_ir.BoundsCheck node) { | 690 Expression visitBoundsCheck(cps_ir.BoundsCheck node) { |
| 682 throw 'Unexpected BoundsCheck node in tree builder'; | 691 throw 'Unexpected BoundsCheck node in tree builder'; |
| 683 } | 692 } |
| 684 | 693 |
| 685 /********** UNUSED VISIT METHODS *************/ | 694 /********** UNUSED VISIT METHODS *************/ |
| 686 | 695 |
| 687 unexpectedNode(cps_ir.Node node) { | 696 unexpectedNode(cps_ir.Node node) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 713 --enclosingFunctions; | 722 --enclosingFunctions; |
| 714 } | 723 } |
| 715 | 724 |
| 716 @override | 725 @override |
| 717 visitInterpolatedNode(js.InterpolatedNode node) { | 726 visitInterpolatedNode(js.InterpolatedNode node) { |
| 718 if (enclosingFunctions > 0) { | 727 if (enclosingFunctions > 0) { |
| 719 found = true; | 728 found = true; |
| 720 } | 729 } |
| 721 } | 730 } |
| 722 } | 731 } |
| OLD | NEW |