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 '../constants/values.dart' as values; | 7 import '../constants/values.dart' as values; |
8 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; | 8 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; |
9 import '../elements/elements.dart'; | 9 import '../elements/elements.dart'; |
10 import '../io/source_information.dart' show SourceInformation; | 10 import '../io/source_information.dart' show SourceInformation; |
(...skipping 1166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1177 bool get isSafeForReordering => true; | 1177 bool get isSafeForReordering => true; |
1178 | 1178 |
1179 toString() => 'CreateInstance($classElement)'; | 1179 toString() => 'CreateInstance($classElement)'; |
1180 | 1180 |
1181 void setParentPointers() { | 1181 void setParentPointers() { |
1182 _setParentsOnList(arguments, this); | 1182 _setParentsOnList(arguments, this); |
1183 if (typeInformation != null) _setParentsOnList(typeInformation, this); | 1183 if (typeInformation != null) _setParentsOnList(typeInformation, this); |
1184 } | 1184 } |
1185 } | 1185 } |
1186 | 1186 |
| 1187 /// Obtains the interceptor for the given value. This is a method table |
| 1188 /// corresponding to the Dart class of the value. |
| 1189 /// |
| 1190 /// All values are either intercepted or self-intercepted. The interceptor for |
| 1191 /// an "intercepted value" is one of the subclasses of Interceptor. |
| 1192 /// The interceptor for a "self-intercepted value" is the value itself. |
| 1193 /// |
| 1194 /// If the input is an intercepted value, and any of its superclasses is in |
| 1195 /// [interceptedClasses], the first such superclass is returned. |
| 1196 /// Otherwise, the input itself is returned. |
| 1197 /// |
| 1198 /// There are thus three significant cases: |
| 1199 /// - the input is a self-interceptor |
| 1200 /// - the input is an intercepted value and is caught by [interceptedClasses] |
| 1201 /// - the input is an intercepted value but is bypassed by [interceptedClasses] |
| 1202 /// |
| 1203 /// The [flags] field indicates which of the above cases may happen, with |
| 1204 /// additional special cases for null (which can either by intercepted or |
| 1205 /// bypassed). |
1187 class Interceptor extends Primitive { | 1206 class Interceptor extends Primitive { |
1188 final Reference<Primitive> input; | 1207 final Reference<Primitive> input; |
1189 final Set<ClassElement> interceptedClasses = new Set<ClassElement>(); | 1208 final Set<ClassElement> interceptedClasses = new Set<ClassElement>(); |
1190 final SourceInformation sourceInformation; | 1209 final SourceInformation sourceInformation; |
1191 | 1210 |
1192 /// If non-null, all uses of this the interceptor call are guaranteed to | 1211 /// The input was a self-interceptor. |
1193 /// see this value. | 1212 static const int SELF_INTERCEPT = 1 << 0; |
1194 /// | 1213 |
1195 /// The interceptor call is not immediately replaced by the constant, because | 1214 /// A non-null value was mapped to an interceptor. |
1196 /// that might prevent the interceptor from being shared. | 1215 static const int NON_NULL_INTERCEPT = 1 << 1; |
1197 /// | 1216 |
1198 /// The precise input type is not known when sharing interceptors, because | 1217 /// A non-null intercepted value was bypassed because none of its supertypes |
1199 /// refinement nodes have been removed by then. So this field carries the | 1218 /// were mentioned in [interceptedClasses]. |
1200 /// known constant until we know if it should be shared or replaced by | 1219 static const int NON_NULL_BYPASS = 1 << 2; |
1201 /// the constant. | 1220 |
1202 values.InterceptorConstantValue constantValue; | 1221 /// Null was returned as-is. |
| 1222 static const int NULL_BYPASS = 1 << 3; |
| 1223 |
| 1224 /// Null was mapped to JSNull. |
| 1225 static const int NULL_INTERCEPT = 1 << 4; |
| 1226 |
| 1227 static const int NULL = NULL_BYPASS | NULL_INTERCEPT; |
| 1228 static const int INTERCEPT = NULL_INTERCEPT | NON_NULL_INTERCEPT; |
| 1229 static const int BYPASS = NULL_BYPASS | NON_NULL_BYPASS; |
| 1230 |
| 1231 static const int ALL_FLAGS = SELF_INTERCEPT | BYPASS | INTERCEPT; |
| 1232 |
| 1233 /// Which of the above cases may happen at runtime. Set by type propagation. |
| 1234 int flags = ALL_FLAGS; |
| 1235 |
| 1236 void clearFlag(int flag) { |
| 1237 flags &= ~flag; |
| 1238 } |
| 1239 |
| 1240 bool get isAlwaysIntercepted => flags & ~INTERCEPT == 0; |
| 1241 bool get isAlwaysNullOrIntercepted => flags & ~(NULL | INTERCEPT) == 0; |
1203 | 1242 |
1204 Interceptor(Primitive input, this.sourceInformation) | 1243 Interceptor(Primitive input, this.sourceInformation) |
1205 : this.input = new Reference<Primitive>(input); | 1244 : this.input = new Reference<Primitive>(input); |
1206 | 1245 |
1207 accept(Visitor visitor) => visitor.visitInterceptor(this); | 1246 accept(Visitor visitor) => visitor.visitInterceptor(this); |
1208 | 1247 |
1209 bool get isSafeForElimination => true; | 1248 bool get isSafeForElimination => true; |
1210 bool get isSafeForReordering => true; | 1249 bool get isSafeForReordering => true; |
1211 | 1250 |
1212 void setParentPointers() { | 1251 void setParentPointers() { |
(...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2072 /// Visit a just-deleted subterm and unlink all [Reference]s in it. | 2111 /// Visit a just-deleted subterm and unlink all [Reference]s in it. |
2073 class RemovalVisitor extends TrampolineRecursiveVisitor { | 2112 class RemovalVisitor extends TrampolineRecursiveVisitor { |
2074 processReference(Reference reference) { | 2113 processReference(Reference reference) { |
2075 reference.unlink(); | 2114 reference.unlink(); |
2076 } | 2115 } |
2077 | 2116 |
2078 static void remove(Node node) { | 2117 static void remove(Node node) { |
2079 (new RemovalVisitor()).visit(node); | 2118 (new RemovalVisitor()).visit(node); |
2080 } | 2119 } |
2081 } | 2120 } |
OLD | NEW |