OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 dart2js.ir_builder_task; | 5 library dart2js.ir_builder_task; |
6 | 6 |
7 import '../closure.dart' as closurelib; | 7 import '../closure.dart' as closurelib; |
8 import '../closure.dart' hide ClosureScope; | 8 import '../closure.dart' hide ClosureScope; |
9 import '../constants/expressions.dart'; | 9 import '../constants/expressions.dart'; |
10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 return irBuilder.buildConditional( | 544 return irBuilder.buildConditional( |
545 build(node.condition), | 545 build(node.condition), |
546 subbuild(node.thenExpression), | 546 subbuild(node.thenExpression), |
547 subbuild(node.elseExpression)); | 547 subbuild(node.elseExpression)); |
548 } | 548 } |
549 | 549 |
550 // For all simple literals: | 550 // For all simple literals: |
551 // Build(Literal(c), C) = C[let val x = Constant(c) in [], x] | 551 // Build(Literal(c), C) = C[let val x = Constant(c) in [], x] |
552 ir.Primitive visitLiteralBool(ast.LiteralBool node) { | 552 ir.Primitive visitLiteralBool(ast.LiteralBool node) { |
553 assert(irBuilder.isOpen); | 553 assert(irBuilder.isOpen); |
554 return translateConstant(node); | 554 return irBuilder.buildBooleanConstant(node.value); |
555 } | 555 } |
556 | 556 |
557 ir.Primitive visitLiteralDouble(ast.LiteralDouble node) { | 557 ir.Primitive visitLiteralDouble(ast.LiteralDouble node) { |
558 assert(irBuilder.isOpen); | 558 assert(irBuilder.isOpen); |
559 return translateConstant(node); | 559 return irBuilder.buildDoubleConstant(node.value); |
560 } | 560 } |
561 | 561 |
562 ir.Primitive visitLiteralInt(ast.LiteralInt node) { | 562 ir.Primitive visitLiteralInt(ast.LiteralInt node) { |
563 assert(irBuilder.isOpen); | 563 assert(irBuilder.isOpen); |
564 return translateConstant(node); | 564 return irBuilder.buildIntegerConstant(node.value); |
565 } | 565 } |
566 | 566 |
567 ir.Primitive visitLiteralNull(ast.LiteralNull node) { | 567 ir.Primitive visitLiteralNull(ast.LiteralNull node) { |
568 assert(irBuilder.isOpen); | 568 assert(irBuilder.isOpen); |
569 return translateConstant(node); | 569 return irBuilder.buildNullConstant(); |
570 } | 570 } |
571 | 571 |
572 ir.Primitive visitLiteralString(ast.LiteralString node) { | 572 ir.Primitive visitLiteralString(ast.LiteralString node) { |
573 assert(irBuilder.isOpen); | 573 assert(irBuilder.isOpen); |
574 return translateConstant(node); | 574 return irBuilder.buildDartStringConstant(node.dartString); |
575 } | 575 } |
576 | 576 |
577 ConstantExpression getConstantForNode(ast.Node node) { | 577 ConstantExpression getConstantForNode(ast.Node node) { |
578 ConstantExpression constant = | 578 ConstantExpression constant = |
579 compiler.backend.constantCompilerTask.compileNode(node, elements); | 579 compiler.backend.constants.getConstantForNode(node, elements); |
580 assert(invariant(node, constant != null, | 580 assert(invariant(node, constant != null, |
581 message: 'No constant computed for $node')); | 581 message: 'No constant computed for $node')); |
582 return constant; | 582 return constant; |
583 } | 583 } |
584 | 584 |
585 ConstantExpression getConstantForVariable(VariableElement element) { | 585 ConstantExpression getConstantForVariable(VariableElement element) { |
586 ConstantExpression constant = | 586 ConstantExpression constant = |
587 compiler.backend.constants.getConstantForVariable(element); | 587 compiler.backend.constants.getConstantForVariable(element); |
588 assert(invariant(element, constant != null, | 588 assert(invariant(element, constant != null, |
589 message: 'No constant computed for $element')); | 589 message: 'No constant computed for $element')); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 /// Returns `true` if [node] is a super call. | 683 /// Returns `true` if [node] is a super call. |
684 // TODO(johnniwinther): Remove the need for this. | 684 // TODO(johnniwinther): Remove the need for this. |
685 bool isSuperCall(ast.Send node) { | 685 bool isSuperCall(ast.Send node) { |
686 return node != null && node.receiver != null && node.receiver.isSuper(); | 686 return node != null && node.receiver != null && node.receiver.isSuper(); |
687 } | 687 } |
688 | 688 |
689 @override | 689 @override |
690 ir.Primitive handleConstantGet( | 690 ir.Primitive handleConstantGet( |
691 ast.Node node, | 691 ast.Node node, |
692 ConstantExpression constant, _) { | 692 ConstantExpression constant, _) { |
693 return irBuilder.buildConstantLiteral(constant); | 693 return irBuilder.buildConstant(constant); |
694 } | 694 } |
695 | 695 |
696 /// If [node] is null, returns this. | 696 /// If [node] is null, returns this. |
697 /// Otherwise visits [node] and returns the result. | 697 /// Otherwise visits [node] and returns the result. |
698 ir.Primitive translateReceiver(ast.Expression node) { | 698 ir.Primitive translateReceiver(ast.Expression node) { |
699 return node != null ? visit(node) : irBuilder.buildThis(); | 699 return node != null ? visit(node) : irBuilder.buildThis(); |
700 } | 700 } |
701 | 701 |
702 @override | 702 @override |
703 ir.Primitive handleDynamicGet( | 703 ir.Primitive handleDynamicGet( |
704 ast.Send node, | 704 ast.Send node, |
705 ast.Node receiver, | 705 ast.Node receiver, |
706 Selector selector, | 706 Selector selector, |
707 _) { | 707 _) { |
708 return irBuilder.buildDynamicGet( | 708 return irBuilder.buildDynamicGet( |
709 translateReceiver(receiver), | 709 translateReceiver(receiver), |
710 selector); | 710 selector); |
711 } | 711 } |
712 | 712 |
713 @override | 713 @override |
714 ir.Primitive visitDynamicTypeLiteralGet( | 714 ir.Primitive visitDynamicTypeLiteralGet( |
715 ast.Send node, | 715 ast.Send node, |
716 ConstantExpression constant, | 716 ConstantExpression constant, |
717 _) { | 717 _) { |
718 return irBuilder.buildConstantLiteral(constant); | 718 return irBuilder.buildConstant(constant); |
719 } | 719 } |
720 | 720 |
721 @override | 721 @override |
| 722 ir.Primitive visitLocalVariableGet( |
| 723 ast.Send node, |
| 724 LocalVariableElement element, |
| 725 _) { |
| 726 return element.isConst |
| 727 ? irBuilder.buildConstant(getConstantForVariable(element)) |
| 728 : irBuilder.buildLocalVariableGet(element); |
| 729 } |
| 730 |
| 731 @override |
722 ir.Primitive handleLocalGet( | 732 ir.Primitive handleLocalGet( |
723 ast.Send node, | 733 ast.Send node, |
724 LocalElement element, | 734 LocalElement element, |
725 _) { | 735 _) { |
726 if (element.isConst) { | |
727 return translateConstant(node); | |
728 } | |
729 return irBuilder.buildLocalVariableGet(element); | 736 return irBuilder.buildLocalVariableGet(element); |
730 } | 737 } |
731 | 738 |
732 @override | 739 @override |
733 ir.Primitive visitLocalFunctionGet( | 740 ir.Primitive visitLocalFunctionGet( |
734 ast.Send node, | 741 ast.Send node, |
735 LocalFunctionElement function, | 742 LocalFunctionElement function, |
736 _) { | 743 _) { |
737 return irBuilder.buildLocalFunctionGet(function); | 744 return irBuilder.buildLocalFunctionGet(function); |
738 } | 745 } |
739 | 746 |
740 @override | 747 @override |
741 ir.Primitive handleStaticFieldGet( | 748 ir.Primitive handleStaticFieldGet(ast.Send node, FieldElement field, _) { |
742 ast.Send node, | 749 return field.isConst |
743 FieldElement field, | 750 ? irBuilder.buildConstant(getConstantForVariable(field)) |
744 _) { | 751 : irBuilder.buildStaticFieldGet(field, |
745 if (field.isConst) { | 752 sourceInformation: sourceInformationBuilder.buildGet(node)); |
746 return translateConstant(node); | |
747 } | |
748 return irBuilder.buildStaticFieldGet(field, | |
749 sourceInformation: sourceInformationBuilder.buildGet(node)); | |
750 } | 753 } |
751 | 754 |
752 @override | 755 @override |
753 ir.Primitive handleStaticFunctionGet( | 756 ir.Primitive handleStaticFunctionGet( |
754 ast.Send node, | 757 ast.Send node, |
755 MethodElement function, | 758 MethodElement function, |
756 _) { | 759 _) { |
757 // TODO(karlklose): support foreign functions. | 760 // TODO(karlklose): support foreign functions. |
758 if (function.isForeign(compiler.backend)) { | 761 if (function.isForeign(compiler.backend)) { |
759 return giveup(node, 'handleStaticFunctionGet: foreign: $function'); | 762 return giveup(node, 'handleStaticFunctionGet: foreign: $function'); |
760 } | 763 } |
761 return translateConstant(node); | 764 return giveup(node, 'handleStaticFunctionGet: $function'); |
762 } | 765 } |
763 | 766 |
764 @override | 767 @override |
765 ir.Primitive handleStaticGetterGet( | 768 ir.Primitive handleStaticGetterGet( |
766 ast.Send node, | 769 ast.Send node, |
767 FunctionElement getter, | 770 FunctionElement getter, |
768 _) { | 771 _) { |
769 return irBuilder.buildStaticGetterGet(getter); | 772 return irBuilder.buildStaticGetterGet(getter); |
770 } | 773 } |
771 | 774 |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1017 translateDynamicArguments(arguments, callStructure)); | 1020 translateDynamicArguments(arguments, callStructure)); |
1018 } | 1021 } |
1019 | 1022 |
1020 @override | 1023 @override |
1021 ir.Primitive handleConstantInvoke( | 1024 ir.Primitive handleConstantInvoke( |
1022 ast.Send node, | 1025 ast.Send node, |
1023 ConstantExpression constant, | 1026 ConstantExpression constant, |
1024 ast.NodeList arguments, | 1027 ast.NodeList arguments, |
1025 CallStructure callStructure, | 1028 CallStructure callStructure, |
1026 _) { | 1029 _) { |
1027 return translateCallInvoke( | 1030 ir.Primitive target = irBuilder.buildConstant(constant); |
1028 irBuilder.buildConstantLiteral(constant), | 1031 return translateCallInvoke(target, arguments, callStructure); |
1029 arguments, | |
1030 callStructure); | |
1031 } | 1032 } |
1032 | 1033 |
1033 @override | 1034 @override |
1034 ir.Primitive handleDynamicInvoke( | 1035 ir.Primitive handleDynamicInvoke( |
1035 ast.Send node, | 1036 ast.Send node, |
1036 ast.Node receiver, | 1037 ast.Node receiver, |
1037 ast.NodeList arguments, | 1038 ast.NodeList arguments, |
1038 Selector selector, | 1039 Selector selector, |
1039 _) { | 1040 _) { |
1040 return irBuilder.buildDynamicInvocation( | 1041 return irBuilder.buildDynamicInvocation( |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1092 sourceInformation: sourceInformationBuilder.buildCall(node)); | 1093 sourceInformation: sourceInformationBuilder.buildCall(node)); |
1093 } | 1094 } |
1094 | 1095 |
1095 @override | 1096 @override |
1096 ir.Primitive handleStaticGetterInvoke( | 1097 ir.Primitive handleStaticGetterInvoke( |
1097 ast.Send node, | 1098 ast.Send node, |
1098 FunctionElement getter, | 1099 FunctionElement getter, |
1099 ast.NodeList arguments, | 1100 ast.NodeList arguments, |
1100 CallStructure callStructure, | 1101 CallStructure callStructure, |
1101 _) { | 1102 _) { |
| 1103 if (getter.isForeign(compiler.backend)) { |
| 1104 return giveup(node, 'handleStaticGetterInvoke: foreign: $getter'); |
| 1105 } |
1102 ir.Primitive target = irBuilder.buildStaticGetterGet(getter); | 1106 ir.Primitive target = irBuilder.buildStaticGetterGet(getter); |
1103 return irBuilder.buildCallInvocation(target, | 1107 return irBuilder.buildCallInvocation(target, |
1104 callStructure, | 1108 callStructure, |
1105 translateDynamicArguments(arguments, callStructure)); | 1109 translateDynamicArguments(arguments, callStructure)); |
1106 } | 1110 } |
1107 | 1111 |
1108 @override | 1112 @override |
1109 ir.Primitive visitSuperFieldInvoke( | 1113 ir.Primitive visitSuperFieldInvoke( |
1110 ast.Send node, | 1114 ast.Send node, |
1111 FieldElement field, | 1115 FieldElement field, |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1237 | 1241 |
1238 ir.Primitive translatePrefixPostfix( | 1242 ir.Primitive translatePrefixPostfix( |
1239 {ir.Primitive getValue(), | 1243 {ir.Primitive getValue(), |
1240 op.IncDecOperator operator, | 1244 op.IncDecOperator operator, |
1241 void setValue(ir.Primitive value), | 1245 void setValue(ir.Primitive value), |
1242 bool isPrefix}) { | 1246 bool isPrefix}) { |
1243 ir.Primitive value = getValue(); | 1247 ir.Primitive value = getValue(); |
1244 Selector operatorSelector = | 1248 Selector operatorSelector = |
1245 new Selector.binaryOperator(operator.selectorName); | 1249 new Selector.binaryOperator(operator.selectorName); |
1246 List<ir.Primitive> arguments = | 1250 List<ir.Primitive> arguments = |
1247 <ir.Primitive>[irBuilder.buildIntegerLiteral(1)]; | 1251 <ir.Primitive>[irBuilder.buildIntegerConstant(1)]; |
1248 arguments = normalizeDynamicArguments( | 1252 arguments = normalizeDynamicArguments( |
1249 operatorSelector.callStructure, arguments); | 1253 operatorSelector.callStructure, arguments); |
1250 ir.Primitive result = | 1254 ir.Primitive result = |
1251 irBuilder.buildDynamicInvocation(value, operatorSelector, arguments); | 1255 irBuilder.buildDynamicInvocation(value, operatorSelector, arguments); |
1252 setValue(result); | 1256 setValue(result); |
1253 return isPrefix ? result : value; | 1257 return isPrefix ? result : value; |
1254 } | 1258 } |
1255 | 1259 |
1256 ir.Primitive translateCompound( | 1260 ir.Primitive translateCompound( |
1257 {ir.Primitive getValue(), | 1261 {ir.Primitive getValue(), |
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1764 while (it.moveNext()) { | 1768 while (it.moveNext()) { |
1765 ast.StringInterpolationPart part = it.current; | 1769 ast.StringInterpolationPart part = it.current; |
1766 arguments.add(visit(part.expression)); | 1770 arguments.add(visit(part.expression)); |
1767 arguments.add(visitLiteralString(part.string)); | 1771 arguments.add(visitLiteralString(part.string)); |
1768 } | 1772 } |
1769 return irBuilder.buildStringConcatenation(arguments); | 1773 return irBuilder.buildStringConcatenation(arguments); |
1770 } | 1774 } |
1771 | 1775 |
1772 ir.Primitive translateConstant(ast.Node node) { | 1776 ir.Primitive translateConstant(ast.Node node) { |
1773 assert(irBuilder.isOpen); | 1777 assert(irBuilder.isOpen); |
1774 return irBuilder.buildConstantLiteral(getConstantForNode(node)); | 1778 return irBuilder.buildConstant(getConstantForNode(node)); |
1775 } | 1779 } |
1776 | 1780 |
1777 ir.Primitive visitThrow(ast.Throw node) { | 1781 ir.Primitive visitThrow(ast.Throw node) { |
1778 assert(irBuilder.isOpen); | 1782 assert(irBuilder.isOpen); |
1779 // This function is not called for throw expressions occurring as | 1783 // This function is not called for throw expressions occurring as |
1780 // statements. | 1784 // statements. |
1781 return irBuilder.buildNonTailThrow(visit(node.expression)); | 1785 return irBuilder.buildNonTailThrow(visit(node.expression)); |
1782 } | 1786 } |
1783 | 1787 |
1784 ir.RootNode nullIfGiveup(ir.RootNode action()) { | 1788 ir.RootNode nullIfGiveup(ir.RootNode action()) { |
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2413 ClassElement enclosingClass = constructor.enclosingClass.implementation; | 2417 ClassElement enclosingClass = constructor.enclosingClass.implementation; |
2414 enclosingClass.forEachInstanceField((ClassElement c, FieldElement field) { | 2418 enclosingClass.forEachInstanceField((ClassElement c, FieldElement field) { |
2415 if (field.initializer != null) { | 2419 if (field.initializer != null) { |
2416 fieldValues[field] = inlineExpression(field, field.initializer); | 2420 fieldValues[field] = inlineExpression(field, field.initializer); |
2417 } else { | 2421 } else { |
2418 if (Elements.isNativeOrExtendsNative(c)) { | 2422 if (Elements.isNativeOrExtendsNative(c)) { |
2419 // Native field is initialized elsewhere. | 2423 // Native field is initialized elsewhere. |
2420 } else { | 2424 } else { |
2421 // Fields without an initializer default to null. | 2425 // Fields without an initializer default to null. |
2422 // This value will be overwritten below if an initializer is found. | 2426 // This value will be overwritten below if an initializer is found. |
2423 fieldValues[field] = irBuilder.buildNullLiteral(); | 2427 fieldValues[field] = irBuilder.buildNullConstant(); |
2424 } | 2428 } |
2425 } | 2429 } |
2426 }); | 2430 }); |
2427 // Evaluate initializing parameters, e.g. `Foo(this.x)`. | 2431 // Evaluate initializing parameters, e.g. `Foo(this.x)`. |
2428 constructor.functionSignature.orderedForEachParameter( | 2432 constructor.functionSignature.orderedForEachParameter( |
2429 (ParameterElement parameter) { | 2433 (ParameterElement parameter) { |
2430 if (parameter.isInitializingFormal) { | 2434 if (parameter.isInitializingFormal) { |
2431 InitializingFormalElement fieldParameter = parameter; | 2435 InitializingFormalElement fieldParameter = parameter; |
2432 fieldValues[fieldParameter.fieldElement] = | 2436 fieldValues[fieldParameter.fieldElement] = |
2433 irBuilder.buildLocalVariableGet(parameter); | 2437 irBuilder.buildLocalVariableGet(parameter); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2503 value = arguments[translatedIndex]; | 2507 value = arguments[translatedIndex]; |
2504 } | 2508 } |
2505 } else if (index < arguments.length) { | 2509 } else if (index < arguments.length) { |
2506 value = arguments[index]; | 2510 value = arguments[index]; |
2507 } | 2511 } |
2508 // Load default if argument was not provided. | 2512 // Load default if argument was not provided. |
2509 if (value == null) { | 2513 if (value == null) { |
2510 if (param.initializer != null) { | 2514 if (param.initializer != null) { |
2511 value = inlineExpression(target, param.initializer); | 2515 value = inlineExpression(target, param.initializer); |
2512 } else { | 2516 } else { |
2513 value = irBuilder.buildNullLiteral(); | 2517 value = irBuilder.buildNullConstant(); |
2514 } | 2518 } |
2515 } | 2519 } |
2516 irBuilder.declareLocalVariable(param, initialValue: value); | 2520 irBuilder.declareLocalVariable(param, initialValue: value); |
2517 index++; | 2521 index++; |
2518 }); | 2522 }); |
2519 } | 2523 } |
2520 | 2524 |
2521 /** | 2525 /** |
2522 * Returns the constructor body associated with the given constructor or | 2526 * Returns the constructor body associated with the given constructor or |
2523 * creates a new constructor body, if none can be found. | 2527 * creates a new constructor body, if none can be found. |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2651 elements); | 2655 elements); |
2652 DartCapturedVariables variables = _analyzeCapturedVariables(node); | 2656 DartCapturedVariables variables = _analyzeCapturedVariables(node); |
2653 tryStatements = variables.tryStatements; | 2657 tryStatements = variables.tryStatements; |
2654 IrBuilder builder = getBuilderFor(element); | 2658 IrBuilder builder = getBuilderFor(element); |
2655 return withBuilder(builder, () => _makeFunctionBody(element, node)); | 2659 return withBuilder(builder, () => _makeFunctionBody(element, node)); |
2656 } | 2660 } |
2657 | 2661 |
2658 /// Creates a primitive for the default value of [parameter]. | 2662 /// Creates a primitive for the default value of [parameter]. |
2659 ir.Primitive translateDefaultValue(ParameterElement parameter) { | 2663 ir.Primitive translateDefaultValue(ParameterElement parameter) { |
2660 if (parameter.initializer == null) { | 2664 if (parameter.initializer == null) { |
2661 return irBuilder.buildNullLiteral(); | 2665 return irBuilder.buildNullConstant(); |
2662 } else { | 2666 } else { |
2663 return inlineConstant(parameter.executableContext, parameter.initializer); | 2667 return inlineConstant(parameter.executableContext, parameter.initializer); |
2664 } | 2668 } |
2665 } | 2669 } |
2666 | 2670 |
2667 /// Inserts default arguments and normalizes order of named arguments. | 2671 /// Inserts default arguments and normalizes order of named arguments. |
2668 List<ir.Primitive> normalizeStaticArguments( | 2672 List<ir.Primitive> normalizeStaticArguments( |
2669 CallStructure callStructure, | 2673 CallStructure callStructure, |
2670 FunctionElement target, | 2674 FunctionElement target, |
2671 List<ir.Primitive> arguments) { | 2675 List<ir.Primitive> arguments) { |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2862 } | 2866 } |
2863 } | 2867 } |
2864 | 2868 |
2865 /// Visit a just-deleted subterm and unlink all [Reference]s in it. | 2869 /// Visit a just-deleted subterm and unlink all [Reference]s in it. |
2866 class RemovalVisitor extends ir.RecursiveVisitor { | 2870 class RemovalVisitor extends ir.RecursiveVisitor { |
2867 processReference(ir.Reference reference) { | 2871 processReference(ir.Reference reference) { |
2868 reference.unlink(); | 2872 reference.unlink(); |
2869 } | 2873 } |
2870 } | 2874 } |
2871 | 2875 |
OLD | NEW |