| 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_nodes; | 5 library tree_ir_nodes; |
| 6 | 6 |
| 7 import '../constants/expressions.dart'; | 7 import '../constants/expressions.dart'; |
| 8 import '../constants/values.dart' as values; | 8 import '../constants/values.dart' as values; |
| 9 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; | 9 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; |
| 10 import '../elements/elements.dart'; | 10 import '../elements/elements.dart'; |
| 11 import '../io/source_information.dart' show SourceInformation; | 11 import '../io/source_information.dart' show SourceInformation; |
| 12 import '../universe/universe.dart' show Selector; | 12 import '../universe/universe.dart' show Selector; |
| 13 | 13 |
| 14 // These imports are only used for the JavaScript specific nodes. If we want to |
| 15 // support more than one native backend, we should probably create better |
| 16 // abstractions for native code and its type and effect system. |
| 17 import '../js/js.dart' as js show Template; |
| 18 import '../native/native.dart' as native show NativeBehavior; |
| 19 import '../types/types.dart' as types show TypeMask; |
| 20 |
| 14 // The Tree language is the target of translation out of the CPS-based IR. | 21 // The Tree language is the target of translation out of the CPS-based IR. |
| 15 // | 22 // |
| 16 // The translation from CPS to Dart consists of several stages. Among the | 23 // The translation from CPS to Dart consists of several stages. Among the |
| 17 // stages are translation to direct style, translation out of SSA, eliminating | 24 // stages are translation to direct style, translation out of SSA, eliminating |
| 18 // unnecessary names, recognizing high-level control constructs. Combining | 25 // unnecessary names, recognizing high-level control constructs. Combining |
| 19 // these separate concerns is complicated and the constraints of the CPS-based | 26 // these separate concerns is complicated and the constraints of the CPS-based |
| 20 // language do not permit a multi-stage translation. | 27 // language do not permit a multi-stage translation. |
| 21 // | 28 // |
| 22 // For that reason, CPS is translated to the direct-style language Tree. | 29 // For that reason, CPS is translated to the direct-style language Tree. |
| 23 // Translation out of SSA, unnaming, and control-flow, as well as 'instruction | 30 // Translation out of SSA, unnaming, and control-flow, as well as 'instruction |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 * A call to a static function or getter/setter to a static field. | 171 * A call to a static function or getter/setter to a static field. |
| 165 * | 172 * |
| 166 * In contrast to the CPS-based IR, the arguments can be arbitrary expressions. | 173 * In contrast to the CPS-based IR, the arguments can be arbitrary expressions. |
| 167 */ | 174 */ |
| 168 class InvokeStatic extends Expression implements Invoke { | 175 class InvokeStatic extends Expression implements Invoke { |
| 169 final Entity target; | 176 final Entity target; |
| 170 final List<Expression> arguments; | 177 final List<Expression> arguments; |
| 171 final Selector selector; | 178 final Selector selector; |
| 172 final SourceInformation sourceInformation; | 179 final SourceInformation sourceInformation; |
| 173 | 180 |
| 181 // TODO(karlklose): this should be a named constructor argument. |
| 174 /// True if the [target] is known not to diverge or read or write any | 182 /// True if the [target] is known not to diverge or read or write any |
| 175 /// mutable state. | 183 /// mutable state. |
| 176 /// | 184 /// |
| 177 /// This is set for calls to `getInterceptor` and `identical` to indicate | 185 /// This is set for calls to `getInterceptor` and `identical` to indicate |
| 178 /// that they can be safely be moved across an impure expression | 186 /// that they can be safely be moved across an impure expression |
| 179 /// (assuming the [arguments] are not affected by the impure expression). | 187 /// (assuming the [arguments] are not affected by the impure expression). |
| 180 bool isEffectivelyConstant = false; | 188 bool isEffectivelyConstant = false; |
| 181 | 189 |
| 182 InvokeStatic(this.target, this.selector, this.arguments, | 190 InvokeStatic(this.target, this.selector, this.arguments, |
| 183 {this.sourceInformation}); | 191 {this.sourceInformation}); |
| (...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 744 | 752 |
| 745 accept(ExpressionVisitor visitor) { | 753 accept(ExpressionVisitor visitor) { |
| 746 return visitor.visitCreateInvocationMirror(this); | 754 return visitor.visitCreateInvocationMirror(this); |
| 747 } | 755 } |
| 748 | 756 |
| 749 accept1(ExpressionVisitor1 visitor, arg) { | 757 accept1(ExpressionVisitor1 visitor, arg) { |
| 750 return visitor.visitCreateInvocationMirror(this, arg); | 758 return visitor.visitCreateInvocationMirror(this, arg); |
| 751 } | 759 } |
| 752 } | 760 } |
| 753 | 761 |
| 762 class ForeignCode extends Node { |
| 763 final js.Template codeTemplate; |
| 764 final types.TypeMask type; |
| 765 final List<Expression> arguments; |
| 766 final native.NativeBehavior nativeBehavior; |
| 767 final Element dependency; |
| 768 |
| 769 ForeignCode(this.codeTemplate, this.type, this.arguments, this.nativeBehavior, |
| 770 this.dependency); |
| 771 } |
| 772 |
| 773 class ForeignExpression extends ForeignCode implements Expression { |
| 774 ForeignExpression(js.Template codeTemplate, types.TypeMask type, |
| 775 List<Expression> arguments, native.NativeBehavior nativeBehavior, |
| 776 Element dependency) |
| 777 : super(codeTemplate, type, arguments, nativeBehavior, |
| 778 dependency); |
| 779 |
| 780 accept(ExpressionVisitor visitor) { |
| 781 return visitor.visitForeignExpression(this); |
| 782 } |
| 783 |
| 784 accept1(ExpressionVisitor1 visitor, arg) { |
| 785 return visitor.visitForeignExpression(this, arg); |
| 786 } |
| 787 } |
| 788 |
| 789 class ForeignStatement extends ForeignCode implements Statement { |
| 790 ForeignStatement(js.Template codeTemplate, types.TypeMask type, |
| 791 List<Expression> arguments, native.NativeBehavior nativeBehavior, |
| 792 Element dependency) |
| 793 : super(codeTemplate, type, arguments, nativeBehavior, |
| 794 dependency); |
| 795 |
| 796 accept(StatementVisitor visitor) { |
| 797 return visitor.visitForeignStatement(this); |
| 798 } |
| 799 |
| 800 accept1(StatementVisitor1 visitor, arg) { |
| 801 return visitor.visitForeignStatement(this, arg); |
| 802 } |
| 803 |
| 804 @override |
| 805 Statement get next => null; |
| 806 |
| 807 @override |
| 808 void set next(Statement s) => throw 'UNREACHABLE'; |
| 809 } |
| 810 |
| 754 /// Denotes the internal representation of [dartType], where all type variables | 811 /// Denotes the internal representation of [dartType], where all type variables |
| 755 /// are replaced by the values in [arguments]. | 812 /// are replaced by the values in [arguments]. |
| 756 /// (See documentation on the TypeExpression CPS node for more details.) | 813 /// (See documentation on the TypeExpression CPS node for more details.) |
| 757 class TypeExpression extends Expression { | 814 class TypeExpression extends Expression { |
| 758 final DartType dartType; | 815 final DartType dartType; |
| 759 final List<Expression> arguments; | 816 final List<Expression> arguments; |
| 760 | 817 |
| 761 TypeExpression(this.dartType, this.arguments); | 818 TypeExpression(this.dartType, this.arguments); |
| 762 | 819 |
| 763 accept(ExpressionVisitor visitor) { | 820 accept(ExpressionVisitor visitor) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 790 E visitGetField(GetField node); | 847 E visitGetField(GetField node); |
| 791 E visitSetField(SetField node); | 848 E visitSetField(SetField node); |
| 792 E visitGetStatic(GetStatic node); | 849 E visitGetStatic(GetStatic node); |
| 793 E visitSetStatic(SetStatic node); | 850 E visitSetStatic(SetStatic node); |
| 794 E visitCreateBox(CreateBox node); | 851 E visitCreateBox(CreateBox node); |
| 795 E visitCreateInstance(CreateInstance node); | 852 E visitCreateInstance(CreateInstance node); |
| 796 E visitReifyRuntimeType(ReifyRuntimeType node); | 853 E visitReifyRuntimeType(ReifyRuntimeType node); |
| 797 E visitReadTypeVariable(ReadTypeVariable node); | 854 E visitReadTypeVariable(ReadTypeVariable node); |
| 798 E visitTypeExpression(TypeExpression node); | 855 E visitTypeExpression(TypeExpression node); |
| 799 E visitCreateInvocationMirror(CreateInvocationMirror node); | 856 E visitCreateInvocationMirror(CreateInvocationMirror node); |
| 857 E visitForeignExpression(ForeignExpression node); |
| 800 } | 858 } |
| 801 | 859 |
| 802 abstract class ExpressionVisitor1<E, A> { | 860 abstract class ExpressionVisitor1<E, A> { |
| 803 E visitExpression(Expression node, A arg) => node.accept1(this, arg); | 861 E visitExpression(Expression node, A arg) => node.accept1(this, arg); |
| 804 E visitVariableUse(VariableUse node, A arg); | 862 E visitVariableUse(VariableUse node, A arg); |
| 805 E visitAssign(Assign node, A arg); | 863 E visitAssign(Assign node, A arg); |
| 806 E visitInvokeStatic(InvokeStatic node, A arg); | 864 E visitInvokeStatic(InvokeStatic node, A arg); |
| 807 E visitInvokeMethod(InvokeMethod node, A arg); | 865 E visitInvokeMethod(InvokeMethod node, A arg); |
| 808 E visitInvokeMethodDirectly(InvokeMethodDirectly node, A arg); | 866 E visitInvokeMethodDirectly(InvokeMethodDirectly node, A arg); |
| 809 E visitInvokeConstructor(InvokeConstructor node, A arg); | 867 E visitInvokeConstructor(InvokeConstructor node, A arg); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 820 E visitGetField(GetField node, A arg); | 878 E visitGetField(GetField node, A arg); |
| 821 E visitSetField(SetField node, A arg); | 879 E visitSetField(SetField node, A arg); |
| 822 E visitGetStatic(GetStatic node, A arg); | 880 E visitGetStatic(GetStatic node, A arg); |
| 823 E visitSetStatic(SetStatic node, A arg); | 881 E visitSetStatic(SetStatic node, A arg); |
| 824 E visitCreateBox(CreateBox node, A arg); | 882 E visitCreateBox(CreateBox node, A arg); |
| 825 E visitCreateInstance(CreateInstance node, A arg); | 883 E visitCreateInstance(CreateInstance node, A arg); |
| 826 E visitReifyRuntimeType(ReifyRuntimeType node, A arg); | 884 E visitReifyRuntimeType(ReifyRuntimeType node, A arg); |
| 827 E visitReadTypeVariable(ReadTypeVariable node, A arg); | 885 E visitReadTypeVariable(ReadTypeVariable node, A arg); |
| 828 E visitTypeExpression(TypeExpression node, A arg); | 886 E visitTypeExpression(TypeExpression node, A arg); |
| 829 E visitCreateInvocationMirror(CreateInvocationMirror node, A arg); | 887 E visitCreateInvocationMirror(CreateInvocationMirror node, A arg); |
| 888 E visitForeignExpression(ForeignExpression node, A arg); |
| 830 } | 889 } |
| 831 | 890 |
| 832 abstract class StatementVisitor<S> { | 891 abstract class StatementVisitor<S> { |
| 833 S visitStatement(Statement node) => node.accept(this); | 892 S visitStatement(Statement node) => node.accept(this); |
| 834 S visitLabeledStatement(LabeledStatement node); | 893 S visitLabeledStatement(LabeledStatement node); |
| 835 S visitReturn(Return node); | 894 S visitReturn(Return node); |
| 836 S visitThrow(Throw node); | 895 S visitThrow(Throw node); |
| 837 S visitRethrow(Rethrow node); | 896 S visitRethrow(Rethrow node); |
| 838 S visitBreak(Break node); | 897 S visitBreak(Break node); |
| 839 S visitContinue(Continue node); | 898 S visitContinue(Continue node); |
| 840 S visitIf(If node); | 899 S visitIf(If node); |
| 841 S visitWhileTrue(WhileTrue node); | 900 S visitWhileTrue(WhileTrue node); |
| 842 S visitWhileCondition(WhileCondition node); | 901 S visitWhileCondition(WhileCondition node); |
| 843 S visitExpressionStatement(ExpressionStatement node); | 902 S visitExpressionStatement(ExpressionStatement node); |
| 844 S visitTry(Try node); | 903 S visitTry(Try node); |
| 845 S visitUnreachable(Unreachable node); | 904 S visitUnreachable(Unreachable node); |
| 905 S visitForeignStatement(ForeignStatement node); |
| 846 } | 906 } |
| 847 | 907 |
| 848 abstract class StatementVisitor1<S, A> { | 908 abstract class StatementVisitor1<S, A> { |
| 849 S visitStatement(Statement node, A arg) => node.accept1(this, arg); | 909 S visitStatement(Statement node, A arg) => node.accept1(this, arg); |
| 850 S visitLabeledStatement(LabeledStatement node, A arg); | 910 S visitLabeledStatement(LabeledStatement node, A arg); |
| 851 S visitReturn(Return node, A arg); | 911 S visitReturn(Return node, A arg); |
| 852 S visitThrow(Throw node, A arg); | 912 S visitThrow(Throw node, A arg); |
| 853 S visitRethrow(Rethrow node, A arg); | 913 S visitRethrow(Rethrow node, A arg); |
| 854 S visitBreak(Break node, A arg); | 914 S visitBreak(Break node, A arg); |
| 855 S visitContinue(Continue node, A arg); | 915 S visitContinue(Continue node, A arg); |
| 856 S visitIf(If node, A arg); | 916 S visitIf(If node, A arg); |
| 857 S visitWhileTrue(WhileTrue node, A arg); | 917 S visitWhileTrue(WhileTrue node, A arg); |
| 858 S visitWhileCondition(WhileCondition node, A arg); | 918 S visitWhileCondition(WhileCondition node, A arg); |
| 859 S visitExpressionStatement(ExpressionStatement node, A arg); | 919 S visitExpressionStatement(ExpressionStatement node, A arg); |
| 860 S visitTry(Try node, A arg); | 920 S visitTry(Try node, A arg); |
| 861 S visitUnreachable(Unreachable node, A arg); | 921 S visitUnreachable(Unreachable node, A arg); |
| 922 S visitForeignStatement(ForeignStatement node, A arg); |
| 862 } | 923 } |
| 863 | 924 |
| 864 abstract class RecursiveVisitor implements StatementVisitor, ExpressionVisitor { | 925 abstract class RecursiveVisitor implements StatementVisitor, ExpressionVisitor { |
| 865 visitExpression(Expression e) => e.accept(this); | 926 visitExpression(Expression e) => e.accept(this); |
| 866 visitStatement(Statement s) => s.accept(this); | 927 visitStatement(Statement s) => s.accept(this); |
| 867 | 928 |
| 868 visitInnerFunction(FunctionDefinition node); | 929 visitInnerFunction(FunctionDefinition node); |
| 869 | 930 |
| 870 visitVariable(Variable variable) {} | 931 visitVariable(Variable variable) {} |
| 871 | 932 |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1017 } | 1078 } |
| 1018 | 1079 |
| 1019 visitTypeExpression(TypeExpression node) { | 1080 visitTypeExpression(TypeExpression node) { |
| 1020 node.arguments.forEach(visitExpression); | 1081 node.arguments.forEach(visitExpression); |
| 1021 } | 1082 } |
| 1022 | 1083 |
| 1023 visitCreateInvocationMirror(CreateInvocationMirror node) { | 1084 visitCreateInvocationMirror(CreateInvocationMirror node) { |
| 1024 node.arguments.forEach(visitExpression); | 1085 node.arguments.forEach(visitExpression); |
| 1025 } | 1086 } |
| 1026 | 1087 |
| 1027 visitUnreachable(Unreachable node) {} | 1088 visitUnreachable(Unreachable node) { |
| 1089 } |
| 1090 |
| 1091 visitForeignCode(ForeignCode node) { |
| 1092 node.arguments.forEach(visitExpression); |
| 1093 } |
| 1094 |
| 1095 visitForeignExpression(ForeignExpression node) => visitForeignCode(node); |
| 1096 visitForeignStatement(ForeignStatement node) => visitForeignCode(node); |
| 1028 } | 1097 } |
| 1029 | 1098 |
| 1030 abstract class Transformer implements ExpressionVisitor<Expression>, | 1099 abstract class Transformer implements ExpressionVisitor<Expression>, |
| 1031 StatementVisitor<Statement> { | 1100 StatementVisitor<Statement> { |
| 1032 Expression visitExpression(Expression e) => e.accept(this); | 1101 Expression visitExpression(Expression e) => e.accept(this); |
| 1033 Statement visitStatement(Statement s) => s.accept(this); | 1102 Statement visitStatement(Statement s) => s.accept(this); |
| 1034 } | 1103 } |
| 1035 | 1104 |
| 1036 class RecursiveTransformer extends Transformer { | 1105 class RecursiveTransformer extends Transformer { |
| 1037 void visitInnerFunction(FunctionDefinition node) { | 1106 void visitInnerFunction(FunctionDefinition node) { |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1215 visitTypeExpression(TypeExpression node) { | 1284 visitTypeExpression(TypeExpression node) { |
| 1216 _replaceExpressions(node.arguments); | 1285 _replaceExpressions(node.arguments); |
| 1217 return node; | 1286 return node; |
| 1218 } | 1287 } |
| 1219 | 1288 |
| 1220 visitCreateInvocationMirror(CreateInvocationMirror node) { | 1289 visitCreateInvocationMirror(CreateInvocationMirror node) { |
| 1221 _replaceExpressions(node.arguments); | 1290 _replaceExpressions(node.arguments); |
| 1222 return node; | 1291 return node; |
| 1223 } | 1292 } |
| 1224 | 1293 |
| 1294 visitForeignExpression(ForeignExpression node) { |
| 1295 _replaceExpressions(node.arguments); |
| 1296 return node; |
| 1297 } |
| 1298 |
| 1299 visitForeignStatement(ForeignStatement node) { |
| 1300 _replaceExpressions(node.arguments); |
| 1301 return node; |
| 1302 } |
| 1303 |
| 1225 visitUnreachable(Unreachable node) { | 1304 visitUnreachable(Unreachable node) { |
| 1226 return node; | 1305 return node; |
| 1227 } | 1306 } |
| 1228 } | 1307 } |
| OLD | NEW |