Chromium Code Reviews| 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 if (thisParameter != null && reference.definition == thisParameter) { | 111 if (thisParameter != null && |
| 112 reference.definition.effectiveDefinition == thisParameter) { | |
| 111 return new This(); | 113 return new This(); |
| 112 } | 114 } |
| 113 return new VariableUse(getVariable(reference.definition)); | 115 return new VariableUse(getVariable(reference.definition)); |
| 114 } | 116 } |
| 115 | 117 |
| 116 Label getLabel(cps_ir.Continuation cont) { | 118 Label getLabel(cps_ir.Continuation cont) { |
| 117 return labels.putIfAbsent(cont, () => new Label()); | 119 return labels.putIfAbsent(cont, () => new Label()); |
| 118 } | 120 } |
| 119 | 121 |
| 120 Variable addFunctionParameter(cps_ir.Parameter parameter) { | 122 Variable addFunctionParameter(cps_ir.Parameter parameter) { |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 445 Expression visitCreateInstance(cps_ir.CreateInstance node) { | 447 Expression visitCreateInstance(cps_ir.CreateInstance node) { |
| 446 return new CreateInstance( | 448 return new CreateInstance( |
| 447 node.classElement, | 449 node.classElement, |
| 448 translateArguments(node.arguments), | 450 translateArguments(node.arguments), |
| 449 translateArguments(node.typeInformation), | 451 translateArguments(node.typeInformation), |
| 450 node.sourceInformation); | 452 node.sourceInformation); |
| 451 } | 453 } |
| 452 | 454 |
| 453 Expression visitGetField(cps_ir.GetField node) { | 455 Expression visitGetField(cps_ir.GetField node) { |
| 454 return new GetField(getVariableUse(node.object), node.field, | 456 return new GetField(getVariableUse(node.object), node.field, |
| 455 objectIsNotNull: node.objectIsNotNull); | 457 objectIsNotNull: !node.object.definition.type.isNullable); |
|
sra1
2015/12/11 02:44:15
Explain why the refined type is not appropriate
asgerf
2015/12/11 10:18:18
It is the refined type.
| |
| 456 } | 458 } |
| 457 | 459 |
| 458 Expression visitCreateBox(cps_ir.CreateBox node) { | 460 Expression visitCreateBox(cps_ir.CreateBox node) { |
| 459 return new CreateBox(); | 461 return new CreateBox(); |
| 460 } | 462 } |
| 461 | 463 |
| 462 Expression visitCreateInvocationMirror(cps_ir.CreateInvocationMirror node) { | 464 Expression visitCreateInvocationMirror(cps_ir.CreateInvocationMirror node) { |
| 463 return new CreateInvocationMirror( | 465 return new CreateInvocationMirror( |
| 464 node.selector, | 466 node.selector, |
| 465 translateArguments(node.arguments)); | 467 translateArguments(node.arguments)); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 546 return new Not(getVariableUse(node.arguments.single)); | 548 return new Not(getVariableUse(node.arguments.single)); |
| 547 } | 549 } |
| 548 return new ApplyBuiltinOperator(node.operator, | 550 return new ApplyBuiltinOperator(node.operator, |
| 549 translateArguments(node.arguments)); | 551 translateArguments(node.arguments)); |
| 550 } | 552 } |
| 551 | 553 |
| 552 Expression visitApplyBuiltinMethod(cps_ir.ApplyBuiltinMethod node) { | 554 Expression visitApplyBuiltinMethod(cps_ir.ApplyBuiltinMethod node) { |
| 553 return new ApplyBuiltinMethod(node.method, | 555 return new ApplyBuiltinMethod(node.method, |
| 554 getVariableUse(node.receiver), | 556 getVariableUse(node.receiver), |
| 555 translateArguments(node.arguments), | 557 translateArguments(node.arguments), |
| 556 receiverIsNotNull: node.receiverIsNotNull); | 558 receiverIsNotNull: !node.receiver.definition.type.isNullable); |
| 557 } | 559 } |
| 558 | 560 |
| 559 Expression visitGetLength(cps_ir.GetLength node) { | 561 Expression visitGetLength(cps_ir.GetLength node) { |
| 560 return new GetLength(getVariableUse(node.object)); | 562 return new GetLength(getVariableUse(node.object)); |
| 561 } | 563 } |
| 562 | 564 |
| 563 Expression visitGetIndex(cps_ir.GetIndex node) { | 565 Expression visitGetIndex(cps_ir.GetIndex node) { |
| 564 return new GetIndex(getVariableUse(node.object), | 566 return new GetIndex(getVariableUse(node.object), |
| 565 getVariableUse(node.index)); | 567 getVariableUse(node.index)); |
| 566 } | 568 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 577 node.sourceInformation); | 579 node.sourceInformation); |
| 578 } | 580 } |
| 579 | 581 |
| 580 Expression visitInvokeMethod(cps_ir.InvokeMethod node) { | 582 Expression visitInvokeMethod(cps_ir.InvokeMethod node) { |
| 581 InvokeMethod invoke = new InvokeMethod( | 583 InvokeMethod invoke = new InvokeMethod( |
| 582 getVariableUse(node.receiver), | 584 getVariableUse(node.receiver), |
| 583 node.selector, | 585 node.selector, |
| 584 node.mask, | 586 node.mask, |
| 585 translateArguments(node.arguments), | 587 translateArguments(node.arguments), |
| 586 node.sourceInformation); | 588 node.sourceInformation); |
| 587 invoke.receiverIsNotNull = node.receiverIsNotNull; | 589 // Sometimes we know the Dart receiver is non-null because it has been |
| 590 // refined, which implies that the JS receiver also can not be null at the | |
| 591 // use-site. Interceptors are not refined, so this information is not | |
| 592 // always available on the JS receiver. | |
| 593 // Also check the JS receiver's type, however, because sometimes we know an | |
| 594 // interceptor is non-null because it intercepts JSNull. | |
| 595 invoke.receiverIsNotNull = | |
| 596 !node.dartReceiver.type.isNullable || | |
| 597 !node.receiver.definition.type.isNullable; | |
| 588 return invoke; | 598 return invoke; |
| 589 } | 599 } |
| 590 | 600 |
| 591 Expression visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) { | 601 Expression visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) { |
| 592 Expression receiver = getVariableUse(node.receiver); | 602 Expression receiver = getVariableUse(node.receiver); |
| 593 List<Expression> arguments = translateArguments(node.arguments); | 603 List<Expression> arguments = translateArguments(node.arguments); |
| 594 return new InvokeMethodDirectly(receiver, node.target, | 604 return new InvokeMethodDirectly(receiver, node.target, |
| 595 node.selector, arguments, node.sourceInformation); | 605 node.selector, arguments, node.sourceInformation); |
| 596 } | 606 } |
| 597 | 607 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 655 return new Yield(getVariableUse(node.input), node.hasStar, next); | 665 return new Yield(getVariableUse(node.input), node.hasStar, next); |
| 656 }; | 666 }; |
| 657 } | 667 } |
| 658 | 668 |
| 659 @override | 669 @override |
| 660 Expression visitAwait(cps_ir.Await node) { | 670 Expression visitAwait(cps_ir.Await node) { |
| 661 return new Await(getVariableUse(node.input)); | 671 return new Await(getVariableUse(node.input)); |
| 662 } | 672 } |
| 663 | 673 |
| 664 @override | 674 @override |
| 665 Expression visitRefinement(cps_ir.Refinement node) { | 675 visitRefinement(cps_ir.Refinement node) { |
| 666 throw 'Unexpected Refinement node in tree builder'; | 676 return (Statement next) => next; // Compile to nothing. |
| 667 } | 677 } |
| 668 | 678 |
| 669 /********** UNUSED VISIT METHODS *************/ | 679 /********** UNUSED VISIT METHODS *************/ |
| 670 | 680 |
| 671 unexpectedNode(cps_ir.Node node) { | 681 unexpectedNode(cps_ir.Node node) { |
| 672 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node'); | 682 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node'); |
| 673 } | 683 } |
| 674 | 684 |
| 675 visitFunctionDefinition(cps_ir.FunctionDefinition node) { | 685 visitFunctionDefinition(cps_ir.FunctionDefinition node) { |
| 676 unexpectedNode(node); | 686 unexpectedNode(node); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 697 --enclosingFunctions; | 707 --enclosingFunctions; |
| 698 } | 708 } |
| 699 | 709 |
| 700 @override | 710 @override |
| 701 visitInterpolatedNode(js.InterpolatedNode node) { | 711 visitInterpolatedNode(js.InterpolatedNode node) { |
| 702 if (enclosingFunctions > 0) { | 712 if (enclosingFunctions > 0) { |
| 703 found = true; | 713 found = true; |
| 704 } | 714 } |
| 705 } | 715 } |
| 706 } | 716 } |
| OLD | NEW |