Index: pkg/compiler/lib/src/cps_ir/type_propagation.dart |
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart |
index 0a2b4cef8060d3aa61435b707c5d6d69397d3fc1..1c2686761a1a069c35e000d96515c3b77eaed9c4 100644 |
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart |
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart |
@@ -40,12 +40,15 @@ class ConstantPropagationLattice { |
final ConstantSystem constantSystem; |
final types.DartTypes dartTypes; |
final AbstractValue anything; |
+ final AbstractValue nullValue; |
ConstantPropagationLattice(TypeMaskSystem typeSystem, |
this.constantSystem, |
this.dartTypes) |
: this.typeSystem = typeSystem, |
- anything = new AbstractValue.nonConstant(typeSystem.dynamicType); |
+ anything = new AbstractValue.nonConstant(typeSystem.dynamicType), |
+ nullValue = new AbstractValue.constantValue( |
+ new NullConstantValue(), new TypeMask.empty()); |
final AbstractValue nothing = new AbstractValue.nothing(); |
@@ -1844,9 +1847,30 @@ class TransformingVisitor extends LeafVisitor { |
<Primitive>[prim, prim, prim], |
node.sourceInformation); |
} |
- if (dartType == dartTypes.coreTypes.numType || |
- dartType == dartTypes.coreTypes.doubleType) { |
- return unaryBuiltinOperator(BuiltinOperator.IsNumber); |
+ if (node.dartType == dartTypes.coreTypes.numType || |
+ node.dartType == dartTypes.coreTypes.doubleType) { |
+ return new ApplyBuiltinOperator( |
+ BuiltinOperator.IsNumber, |
+ <Primitive>[prim], |
+ node.sourceInformation); |
+ } |
+ |
+ AbstractBool isNullableSubtype = |
+ lattice.isSubtypeOf(value, node.dartType, allowNull: true); |
+ AbstractBool isNullPassingTest = |
+ lattice.isSubtypeOf(lattice.nullValue, node.dartType, allowNull: false); |
+ if (isNullableSubtype == AbstractBool.True && |
+ isNullPassingTest == AbstractBool.False) { |
+ // Null is the only value not satisfying the type test. |
+ // Replace the type test with a null-check. |
+ // This has lower priority than the 'typeof'-based tests because |
+ // 'typeof' expressions might give the VM some more useful information. |
+ Primitive nullConst = makeConstantPrimitive(new NullConstantValue()); |
+ insertLetPrim(node.parent, nullConst); |
+ return new ApplyBuiltinOperator( |
+ BuiltinOperator.LooseNeq, |
+ <Primitive>[prim, nullConst], |
+ node.sourceInformation); |
} |
if (dartType.element == functionCompiler.glue.jsFixedArrayClass) { |