Index: pkg/compiler/lib/src/ssa/nodes.dart |
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart |
index f2d1af7022316fca4b1200b6a19a841ebf8575d6..712ff298bf4671b42b0350325a08196fcdd62538 100644 |
--- a/pkg/compiler/lib/src/ssa/nodes.dart |
+++ b/pkg/compiler/lib/src/ssa/nodes.dart |
@@ -2801,23 +2801,29 @@ class HIsViaInterceptor extends HLateInstruction { |
} |
class HTypeConversion extends HCheck { |
- final DartType typeExpression; |
- final int kind; |
- final Selector receiverTypeCheckSelector; |
- final bool contextIsTypeArguments; |
- TypeMask checkedType; // Not final because we refine it. |
- |
+ // Values for [kind]. |
static const int CHECKED_MODE_CHECK = 0; |
static const int ARGUMENT_TYPE_CHECK = 1; |
static const int CAST_TYPE_CHECK = 2; |
static const int BOOLEAN_CONVERSION_CHECK = 3; |
static const int RECEIVER_TYPE_CHECK = 4; |
+ final DartType typeExpression; |
+ final int kind; |
+ // [receiverTypeCheckSelector] is the selector used for a receiver type check |
+ // on open-coded operators, e.g. the not-null check on `x` in `x + 1` would be |
+ // compiled to the following, for which we need the selector `$add`. |
+ // |
+ // if (typeof x != "number") x.$add(); |
+ // |
+ final Selector receiverTypeCheckSelector; |
+ |
+ TypeMask checkedType; // Not final because we refine it. |
+ |
HTypeConversion( |
this.typeExpression, this.kind, TypeMask type, HInstruction input, |
- [this.receiverTypeCheckSelector]) |
- : contextIsTypeArguments = false, |
- checkedType = type, |
+ {this.receiverTypeCheckSelector}) |
+ : checkedType = type, |
super(<HInstruction>[input], type) { |
assert(!isReceiverTypeCheck || receiverTypeCheckSelector != null); |
assert(typeExpression == null || typeExpression.kind != TypeKind.TYPEDEF); |
@@ -2826,21 +2832,21 @@ class HTypeConversion extends HCheck { |
HTypeConversion.withTypeRepresentation(this.typeExpression, this.kind, |
TypeMask type, HInstruction input, HInstruction typeRepresentation) |
- : contextIsTypeArguments = false, |
- checkedType = type, |
+ : checkedType = type, |
super(<HInstruction>[input, typeRepresentation], type), |
receiverTypeCheckSelector = null { |
assert(typeExpression.kind != TypeKind.TYPEDEF); |
sourceElement = input.sourceElement; |
} |
- HTypeConversion.withContext(this.typeExpression, this.kind, TypeMask type, |
- HInstruction input, HInstruction context, |
- {bool this.contextIsTypeArguments}) |
- : super(<HInstruction>[input, context], type), |
- checkedType = type, |
+ HTypeConversion.viaMethodOnType(this.typeExpression, this.kind, TypeMask type, |
+ HInstruction reifiedType, HInstruction input) |
+ : checkedType = type, |
+ super(<HInstruction>[reifiedType, input], type), |
receiverTypeCheckSelector = null { |
- assert(typeExpression.kind != TypeKind.TYPEDEF); |
+ // This form is currently used only for function types. |
+ assert(typeExpression.isFunctionType); |
+ assert(kind == CHECKED_MODE_CHECK || kind == CAST_TYPE_CHECK); |
sourceElement = input.sourceElement; |
} |
@@ -2850,11 +2856,11 @@ class HTypeConversion extends HCheck { |
HInstruction get typeRepresentation => inputs[1]; |
- bool get hasContext { |
- return typeExpression.isFunctionType && inputs.length > 1; |
- } |
+ bool get usesMethodOnType => |
+ typeExpression != null && typeExpression.isFunctionType; |
- HInstruction get context => inputs[1]; |
+ HInstruction get checkedInput => |
+ usesMethodOnType ? inputs[1] : super.checkedInput; |
HInstruction convertType(Compiler compiler, DartType type, int kind) { |
if (typeExpression == type) { |