Index: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart |
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart |
index 19b0543c179877ab2a4d7ba2c7061d8822b6f116..0c28fa4cc9a53283df59ac6913a62231fc5a9492 100644 |
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart |
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart |
@@ -589,24 +589,30 @@ class TypeTest extends Primitive { |
Reference<Primitive> value; |
final DartType dartType; |
- /// If [type] is an [InterfaceType], this holds the internal representation of |
- /// the type arguments to [type]. Since these may reference type variables |
- /// from the enclosing class, they are not constant. |
+ /// If [dartType] is an [InterfaceType], this holds the internal |
+ /// representation of the type arguments to [dartType]. Since these may |
+ /// reference type variables from the enclosing class, they are not constant. |
/// |
- /// If [type] is a [TypeVariableType], this is a singleton list with |
- /// the internal representation of the type held in that type variable. |
+ /// If [dartType] is a [TypeVariableType], this is a singleton list with the |
+ /// internal representation of the type held in that type variable. |
/// |
- /// If [type] is a [FunctionType], this is a singleton list with the |
+ /// If [dartType] is a [FunctionType], this is a singleton list with the |
/// internal representation of that type, |
/// |
/// Otherwise the list is empty. |
final List<Reference<Primitive>> typeArguments; |
+ /// The Interceptor for [value]. May be `null` if the test can be done |
+ /// without an interceptor. May be the same as [value] after self-interceptor |
+ /// optimization. |
+ // TODO(24523): Remove this field. |
+ Reference<Primitive> interceptor; |
+ |
TypeTest(Primitive value, |
this.dartType, |
List<Primitive> typeArguments) |
- : this.value = new Reference<Primitive>(value), |
- this.typeArguments = _referenceList(typeArguments); |
+ : this.value = new Reference<Primitive>(value), |
+ this.typeArguments = _referenceList(typeArguments); |
accept(Visitor visitor) => visitor.visitTypeTest(this); |
@@ -614,6 +620,22 @@ class TypeTest extends Primitive { |
bool get isSafeForReordering => true; |
} |
+/// An "is" type test for a raw type, performed by testing a flag property. |
+/// |
+/// Returns `true` if [interceptor] is for [dartType]. |
+class TypeTestViaFlag extends Primitive { |
+ Reference<Primitive> interceptor; |
+ final DartType dartType; |
+ |
+ TypeTestViaFlag(Primitive interceptor, this.dartType) |
+ : this.interceptor = new Reference<Primitive>(interceptor); |
+ |
+ accept(Visitor visitor) => visitor.visitTypeTestViaFlag(this); |
+ |
+ bool get isSafeForElimination => true; |
+ bool get isSafeForReordering => true; |
+} |
+ |
/// An "as" type cast. |
/// |
/// If [value] is `null` or is an instance of [type], [continuation] is invoked |
@@ -1371,6 +1393,7 @@ abstract class Visitor<T> { |
T visitTypeExpression(TypeExpression node); |
T visitCreateInvocationMirror(CreateInvocationMirror node); |
T visitTypeTest(TypeTest node); |
+ T visitTypeTestViaFlag(TypeTestViaFlag node); |
T visitApplyBuiltinOperator(ApplyBuiltinOperator node); |
T visitApplyBuiltinMethod(ApplyBuiltinMethod node); |
T visitGetLength(GetLength node); |
@@ -1496,9 +1519,16 @@ class LeafVisitor implements Visitor { |
visitTypeTest(TypeTest node) { |
processTypeTest(node); |
processReference(node.value); |
+ if (node.interceptor != null) processReference(node.interceptor); |
node.typeArguments.forEach(processReference); |
} |
+ processTypeTestViaFlag(TypeTestViaFlag node) {} |
+ visitTypeTestViaFlag(TypeTestViaFlag node) { |
+ processTypeTestViaFlag(node); |
+ processReference(node.interceptor); |
+ } |
+ |
processSetMutable(SetMutable node) {} |
visitSetMutable(SetMutable node) { |
processSetMutable(node); |