| 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 library dart2js.ir_nodes; | 4 library dart2js.ir_nodes; |
| 5 | 5 |
| 6 import 'dart:collection'; | 6 import 'dart:collection'; |
| 7 import 'cps_fragment.dart' show CpsFragment; | 7 import 'cps_fragment.dart' show CpsFragment; |
| 8 import 'cps_ir_nodes_sexpr.dart'; | 8 import 'cps_ir_nodes_sexpr.dart'; |
| 9 import '../constants/values.dart' as values; | 9 import '../constants/values.dart' as values; |
| 10 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; | 10 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; |
| (...skipping 1095 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1106 | 1106 |
| 1107 /// Gets the value from a [MutableVariable]. | 1107 /// Gets the value from a [MutableVariable]. |
| 1108 /// | 1108 /// |
| 1109 /// [MutableVariable]s can be seen as ref cells that are not first-class | 1109 /// [MutableVariable]s can be seen as ref cells that are not first-class |
| 1110 /// values. A [LetPrim] with a [GetMutable] can then be seen as: | 1110 /// values. A [LetPrim] with a [GetMutable] can then be seen as: |
| 1111 /// | 1111 /// |
| 1112 /// let prim p = ![variable] in [body] | 1112 /// let prim p = ![variable] in [body] |
| 1113 /// | 1113 /// |
| 1114 class GetMutable extends Primitive { | 1114 class GetMutable extends Primitive { |
| 1115 final Reference<MutableVariable> variableRef; | 1115 final Reference<MutableVariable> variableRef; |
| 1116 final SourceInformation sourceInformation; |
| 1116 | 1117 |
| 1117 MutableVariable get variable => variableRef.definition; | 1118 MutableVariable get variable => variableRef.definition; |
| 1118 | 1119 |
| 1119 GetMutable(MutableVariable variable) | 1120 GetMutable(MutableVariable variable, {this.sourceInformation}) |
| 1120 : this.variableRef = new Reference<MutableVariable>(variable); | 1121 : this.variableRef = new Reference<MutableVariable>(variable); |
| 1121 | 1122 |
| 1122 accept(Visitor visitor) => visitor.visitGetMutable(this); | 1123 accept(Visitor visitor) => visitor.visitGetMutable(this); |
| 1123 | 1124 |
| 1124 bool get hasValue => true; | 1125 bool get hasValue => true; |
| 1125 bool get isSafeForElimination => true; | 1126 bool get isSafeForElimination => true; |
| 1126 bool get isSafeForReordering => false; | 1127 bool get isSafeForReordering => false; |
| 1127 | 1128 |
| 1128 void setParentPointers() { | 1129 void setParentPointers() { |
| 1129 variableRef.parent = this; | 1130 variableRef.parent = this; |
| 1130 } | 1131 } |
| 1131 } | 1132 } |
| 1132 | 1133 |
| 1133 /// Assign a [MutableVariable]. | 1134 /// Assign a [MutableVariable]. |
| 1134 /// | 1135 /// |
| 1135 /// [MutableVariable]s can be seen as ref cells that are not first-class | 1136 /// [MutableVariable]s can be seen as ref cells that are not first-class |
| 1136 /// values. This can be seen as a dereferencing assignment: | 1137 /// values. This can be seen as a dereferencing assignment: |
| 1137 /// | 1138 /// |
| 1138 /// { [variable] := [value]; [body] } | 1139 /// { [variable] := [value]; [body] } |
| 1139 class SetMutable extends Primitive { | 1140 class SetMutable extends Primitive { |
| 1140 final Reference<MutableVariable> variableRef; | 1141 final Reference<MutableVariable> variableRef; |
| 1141 final Reference<Primitive> valueRef; | 1142 final Reference<Primitive> valueRef; |
| 1143 final SourceInformation sourceInformation; |
| 1142 | 1144 |
| 1143 MutableVariable get variable => variableRef.definition; | 1145 MutableVariable get variable => variableRef.definition; |
| 1144 Primitive get value => valueRef.definition; | 1146 Primitive get value => valueRef.definition; |
| 1145 | 1147 |
| 1146 SetMutable(MutableVariable variable, Primitive value) | 1148 SetMutable( |
| 1149 MutableVariable variable, |
| 1150 Primitive value, |
| 1151 {this.sourceInformation}) |
| 1147 : this.variableRef = new Reference<MutableVariable>(variable), | 1152 : this.variableRef = new Reference<MutableVariable>(variable), |
| 1148 this.valueRef = new Reference<Primitive>(value); | 1153 this.valueRef = new Reference<Primitive>(value); |
| 1149 | 1154 |
| 1150 accept(Visitor visitor) => visitor.visitSetMutable(this); | 1155 accept(Visitor visitor) => visitor.visitSetMutable(this); |
| 1151 | 1156 |
| 1152 bool get hasValue => false; | 1157 bool get hasValue => false; |
| 1153 bool get isSafeForElimination => false; | 1158 bool get isSafeForElimination => false; |
| 1154 bool get isSafeForReordering => false; | 1159 bool get isSafeForReordering => false; |
| 1155 | 1160 |
| 1156 void setParentPointers() { | 1161 void setParentPointers() { |
| 1157 variableRef.parent = this; | 1162 variableRef.parent = this; |
| 1158 valueRef.parent = this; | 1163 valueRef.parent = this; |
| 1159 } | 1164 } |
| 1160 } | 1165 } |
| 1161 | 1166 |
| 1162 /// Directly reads from a field on a given object. | 1167 /// Directly reads from a field on a given object. |
| 1163 /// | 1168 /// |
| 1164 /// The [object] must either be `null` or an object that has [field]. | 1169 /// The [object] must either be `null` or an object that has [field]. |
| 1165 class GetField extends Primitive { | 1170 class GetField extends Primitive { |
| 1166 final Reference<Primitive> objectRef; | 1171 final Reference<Primitive> objectRef; |
| 1167 FieldElement field; | 1172 FieldElement field; |
| 1173 final SourceInformation sourceInformation; |
| 1168 | 1174 |
| 1169 /// True if the field never changes value. | 1175 /// True if the field never changes value. |
| 1170 final bool isFinal; | 1176 final bool isFinal; |
| 1171 | 1177 |
| 1172 /// True if the object is known not to be null. | 1178 /// True if the object is known not to be null. |
| 1173 // TODO(asgerf): This is a placeholder until we agree on how to track | 1179 // TODO(asgerf): This is a placeholder until we agree on how to track |
| 1174 // side effects. | 1180 // side effects. |
| 1175 bool objectIsNotNull = false; | 1181 bool objectIsNotNull = false; |
| 1176 | 1182 |
| 1177 Primitive get object => objectRef.definition; | 1183 Primitive get object => objectRef.definition; |
| 1178 | 1184 |
| 1179 GetField(Primitive object, this.field, {this.isFinal: false}) | 1185 GetField( |
| 1186 Primitive object, |
| 1187 this.field, |
| 1188 {this.sourceInformation, |
| 1189 this.isFinal: false}) |
| 1180 : this.objectRef = new Reference<Primitive>(object); | 1190 : this.objectRef = new Reference<Primitive>(object); |
| 1181 | 1191 |
| 1182 accept(Visitor visitor) => visitor.visitGetField(this); | 1192 accept(Visitor visitor) => visitor.visitGetField(this); |
| 1183 | 1193 |
| 1184 bool get hasValue => true; | 1194 bool get hasValue => true; |
| 1185 bool get isSafeForElimination => objectIsNotNull; | 1195 bool get isSafeForElimination => objectIsNotNull; |
| 1186 bool get isSafeForReordering => false; | 1196 bool get isSafeForReordering => false; |
| 1187 | 1197 |
| 1188 toString() => 'GetField($field)'; | 1198 toString() => 'GetField($field)'; |
| 1189 | 1199 |
| 1190 void setParentPointers() { | 1200 void setParentPointers() { |
| 1191 objectRef.parent = this; | 1201 objectRef.parent = this; |
| 1192 } | 1202 } |
| 1193 | 1203 |
| 1194 int get effects => isFinal ? 0 : Effects.dependsOnInstanceField; | 1204 int get effects => isFinal ? 0 : Effects.dependsOnInstanceField; |
| 1195 } | 1205 } |
| 1196 | 1206 |
| 1197 /// Directly assigns to a field on a given object. | 1207 /// Directly assigns to a field on a given object. |
| 1198 class SetField extends Primitive { | 1208 class SetField extends Primitive { |
| 1199 final Reference<Primitive> objectRef; | 1209 final Reference<Primitive> objectRef; |
| 1200 FieldElement field; | 1210 FieldElement field; |
| 1201 final Reference<Primitive> valueRef; | 1211 final Reference<Primitive> valueRef; |
| 1212 final SourceInformation sourceInformation; |
| 1202 | 1213 |
| 1203 Primitive get object => objectRef.definition; | 1214 Primitive get object => objectRef.definition; |
| 1204 Primitive get value => valueRef.definition; | 1215 Primitive get value => valueRef.definition; |
| 1205 | 1216 |
| 1206 SetField(Primitive object, this.field, Primitive value) | 1217 SetField( |
| 1218 Primitive object, |
| 1219 this.field, |
| 1220 Primitive value, |
| 1221 {this.sourceInformation}) |
| 1207 : this.objectRef = new Reference<Primitive>(object), | 1222 : this.objectRef = new Reference<Primitive>(object), |
| 1208 this.valueRef = new Reference<Primitive>(value); | 1223 this.valueRef = new Reference<Primitive>(value); |
| 1209 | 1224 |
| 1210 accept(Visitor visitor) => visitor.visitSetField(this); | 1225 accept(Visitor visitor) => visitor.visitSetField(this); |
| 1211 | 1226 |
| 1212 bool get hasValue => false; | 1227 bool get hasValue => false; |
| 1213 bool get isSafeForElimination => false; | 1228 bool get isSafeForElimination => false; |
| 1214 bool get isSafeForReordering => false; | 1229 bool get isSafeForReordering => false; |
| 1215 | 1230 |
| 1216 void setParentPointers() { | 1231 void setParentPointers() { |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1521 void setParentPointers() { | 1536 void setParentPointers() { |
| 1522 _setParentsOnList(argumentRefs, this); | 1537 _setParentsOnList(argumentRefs, this); |
| 1523 } | 1538 } |
| 1524 } | 1539 } |
| 1525 | 1540 |
| 1526 class ForeignCode extends UnsafePrimitive { | 1541 class ForeignCode extends UnsafePrimitive { |
| 1527 final js.Template codeTemplate; | 1542 final js.Template codeTemplate; |
| 1528 final TypeMask storedType; | 1543 final TypeMask storedType; |
| 1529 final List<Reference<Primitive>> argumentRefs; | 1544 final List<Reference<Primitive>> argumentRefs; |
| 1530 final native.NativeBehavior nativeBehavior; | 1545 final native.NativeBehavior nativeBehavior; |
| 1546 final SourceInformation sourceInformation; |
| 1531 final FunctionElement dependency; | 1547 final FunctionElement dependency; |
| 1532 | 1548 |
| 1533 Primitive argument(int n) => argumentRefs[n].definition; | 1549 Primitive argument(int n) => argumentRefs[n].definition; |
| 1534 Iterable<Primitive> get arguments => _dereferenceList(argumentRefs); | 1550 Iterable<Primitive> get arguments => _dereferenceList(argumentRefs); |
| 1535 | 1551 |
| 1536 ForeignCode(this.codeTemplate, this.storedType, List<Primitive> arguments, | 1552 ForeignCode( |
| 1553 this.codeTemplate, |
| 1554 this.storedType, |
| 1555 List<Primitive> arguments, |
| 1537 this.nativeBehavior, | 1556 this.nativeBehavior, |
| 1557 this.sourceInformation, |
| 1538 {this.dependency}) | 1558 {this.dependency}) |
| 1539 : this.argumentRefs = _referenceList(arguments) { | 1559 : this.argumentRefs = _referenceList(arguments) { |
| 1540 effects = Effects.from(nativeBehavior.sideEffects); | 1560 effects = Effects.from(nativeBehavior.sideEffects); |
| 1541 } | 1561 } |
| 1542 | 1562 |
| 1543 accept(Visitor visitor) => visitor.visitForeignCode(this); | 1563 accept(Visitor visitor) => visitor.visitForeignCode(this); |
| 1544 | 1564 |
| 1545 bool get hasValue => true; | 1565 bool get hasValue => true; |
| 1546 | 1566 |
| 1547 void setParentPointers() { | 1567 void setParentPointers() { |
| (...skipping 1265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2813 getList(node.argumentRefs), | 2833 getList(node.argumentRefs), |
| 2814 node.sourceInformation)..allocationSiteType = node.allocationSiteType; | 2834 node.sourceInformation)..allocationSiteType = node.allocationSiteType; |
| 2815 } | 2835 } |
| 2816 | 2836 |
| 2817 Definition visitTypeCast(TypeCast node) { | 2837 Definition visitTypeCast(TypeCast node) { |
| 2818 return new TypeCast( | 2838 return new TypeCast( |
| 2819 getCopy(node.valueRef), node.dartType, getList(node.typeArgumentRefs)); | 2839 getCopy(node.valueRef), node.dartType, getList(node.typeArgumentRefs)); |
| 2820 } | 2840 } |
| 2821 | 2841 |
| 2822 Definition visitSetMutable(SetMutable node) { | 2842 Definition visitSetMutable(SetMutable node) { |
| 2823 return new SetMutable(getCopy(node.variableRef), getCopy(node.valueRef)); | 2843 return new SetMutable(getCopy(node.variableRef), getCopy(node.valueRef), |
| 2844 sourceInformation: node.sourceInformation); |
| 2824 } | 2845 } |
| 2825 | 2846 |
| 2826 Definition visitSetStatic(SetStatic node) { | 2847 Definition visitSetStatic(SetStatic node) { |
| 2827 return new SetStatic( | 2848 return new SetStatic( |
| 2828 node.element, getCopy(node.valueRef), node.sourceInformation); | 2849 node.element, getCopy(node.valueRef), node.sourceInformation); |
| 2829 } | 2850 } |
| 2830 | 2851 |
| 2831 Definition visitSetField(SetField node) { | 2852 Definition visitSetField(SetField node) { |
| 2832 return new SetField( | 2853 return new SetField( |
| 2833 getCopy(node.objectRef), node.field, getCopy(node.valueRef)); | 2854 getCopy(node.objectRef), node.field, getCopy(node.valueRef), |
| 2855 sourceInformation: node.sourceInformation); |
| 2834 } | 2856 } |
| 2835 | 2857 |
| 2836 Definition visitGetLazyStatic(GetLazyStatic node) { | 2858 Definition visitGetLazyStatic(GetLazyStatic node) { |
| 2837 return new GetLazyStatic(node.element, | 2859 return new GetLazyStatic(node.element, |
| 2838 isFinal: node.isFinal, sourceInformation: node.sourceInformation); | 2860 isFinal: node.isFinal, sourceInformation: node.sourceInformation); |
| 2839 } | 2861 } |
| 2840 | 2862 |
| 2841 Definition visitAwait(Await node) { | 2863 Definition visitAwait(Await node) { |
| 2842 return new Await(getCopy(node.inputRef)); | 2864 return new Await(getCopy(node.inputRef)); |
| 2843 } | 2865 } |
| 2844 | 2866 |
| 2845 Definition visitYield(Yield node) { | 2867 Definition visitYield(Yield node) { |
| 2846 return new Yield(getCopy(node.inputRef), node.hasStar); | 2868 return new Yield(getCopy(node.inputRef), node.hasStar); |
| 2847 } | 2869 } |
| 2848 | 2870 |
| 2849 Definition visitLiteralList(LiteralList node) { | 2871 Definition visitLiteralList(LiteralList node) { |
| 2850 return new LiteralList(node.dartType, getList(node.valueRefs)) | 2872 return new LiteralList(node.dartType, getList(node.valueRefs)) |
| 2851 ..allocationSiteType = node.allocationSiteType; | 2873 ..allocationSiteType = node.allocationSiteType; |
| 2852 } | 2874 } |
| 2853 | 2875 |
| 2854 Definition visitConstant(Constant node) { | 2876 Definition visitConstant(Constant node) { |
| 2855 return new Constant(node.value, sourceInformation: node.sourceInformation); | 2877 return new Constant(node.value, sourceInformation: node.sourceInformation); |
| 2856 } | 2878 } |
| 2857 | 2879 |
| 2858 Definition visitGetMutable(GetMutable node) { | 2880 Definition visitGetMutable(GetMutable node) { |
| 2859 return new GetMutable(getCopy(node.variableRef)); | 2881 return new GetMutable( |
| 2882 getCopy(node.variableRef), sourceInformation: node.sourceInformation); |
| 2860 } | 2883 } |
| 2861 | 2884 |
| 2862 Definition visitParameter(Parameter node) { | 2885 Definition visitParameter(Parameter node) { |
| 2863 return new Parameter(node.hint); | 2886 return new Parameter(node.hint); |
| 2864 } | 2887 } |
| 2865 | 2888 |
| 2866 Definition visitMutableVariable(MutableVariable node) { | 2889 Definition visitMutableVariable(MutableVariable node) { |
| 2867 return new MutableVariable(node.hint); | 2890 return new MutableVariable(node.hint); |
| 2868 } | 2891 } |
| 2869 | 2892 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2965 return new ReceiverCheck( | 2988 return new ReceiverCheck( |
| 2966 getCopy(node.valueRef), node.selector, node.sourceInformation, | 2989 getCopy(node.valueRef), node.selector, node.sourceInformation, |
| 2967 condition: getCopyOrNull(node.conditionRef), | 2990 condition: getCopyOrNull(node.conditionRef), |
| 2968 useSelector: node.useSelector, | 2991 useSelector: node.useSelector, |
| 2969 isNullCheck: node.isNullCheck); | 2992 isNullCheck: node.isNullCheck); |
| 2970 } | 2993 } |
| 2971 | 2994 |
| 2972 Definition visitForeignCode(ForeignCode node) { | 2995 Definition visitForeignCode(ForeignCode node) { |
| 2973 return new ForeignCode(node.codeTemplate, node.storedType, | 2996 return new ForeignCode(node.codeTemplate, node.storedType, |
| 2974 getList(node.argumentRefs), node.nativeBehavior, | 2997 getList(node.argumentRefs), node.nativeBehavior, |
| 2998 node.sourceInformation, |
| 2975 dependency: node.dependency); | 2999 dependency: node.dependency); |
| 2976 } | 3000 } |
| 2977 } | 3001 } |
| 2978 | 3002 |
| 2979 /// A trampolining visitor to copy [FunctionDefinition]s. | 3003 /// A trampolining visitor to copy [FunctionDefinition]s. |
| 2980 class CopyingVisitor extends TrampolineRecursiveVisitor { | 3004 class CopyingVisitor extends TrampolineRecursiveVisitor { |
| 2981 // The visitor maintains a map from original continuations to their copies. | 3005 // The visitor maintains a map from original continuations to their copies. |
| 2982 Map<Continuation, Continuation> _copies = <Continuation, Continuation>{}; | 3006 Map<Continuation, Continuation> _copies = <Continuation, Continuation>{}; |
| 2983 | 3007 |
| 2984 // The visitor uses an auxiliary visitor to copy definitions. | 3008 // The visitor uses an auxiliary visitor to copy definitions. |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3110 plug(new Branch.loose( | 3134 plug(new Branch.loose( |
| 3111 _definitions.getCopy(node.conditionRef), | 3135 _definitions.getCopy(node.conditionRef), |
| 3112 _copies[node.trueContinuation], | 3136 _copies[node.trueContinuation], |
| 3113 _copies[node.falseContinuation])..isStrictCheck = node.isStrictCheck); | 3137 _copies[node.falseContinuation])..isStrictCheck = node.isStrictCheck); |
| 3114 } | 3138 } |
| 3115 | 3139 |
| 3116 visitUnreachable(Unreachable node) { | 3140 visitUnreachable(Unreachable node) { |
| 3117 plug(new Unreachable()); | 3141 plug(new Unreachable()); |
| 3118 } | 3142 } |
| 3119 } | 3143 } |
| OLD | NEW |