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 |