OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 | 4 |
5 import '../closure.dart'; | 5 import '../closure.dart'; |
6 import '../common.dart'; | 6 import '../common.dart'; |
7 import '../compiler.dart' show Compiler; | 7 import '../compiler.dart' show Compiler; |
8 import '../constants/constant_system.dart'; | 8 import '../constants/constant_system.dart'; |
9 import '../constants/values.dart'; | 9 import '../constants/values.dart'; |
10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
(...skipping 2783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2794 accept(HVisitor visitor) => visitor.visitIsViaInterceptor(this); | 2794 accept(HVisitor visitor) => visitor.visitIsViaInterceptor(this); |
2795 toString() => "$interceptor is $typeExpression"; | 2795 toString() => "$interceptor is $typeExpression"; |
2796 int typeCode() => HInstruction.IS_VIA_INTERCEPTOR_TYPECODE; | 2796 int typeCode() => HInstruction.IS_VIA_INTERCEPTOR_TYPECODE; |
2797 bool typeEquals(HInstruction other) => other is HIsViaInterceptor; | 2797 bool typeEquals(HInstruction other) => other is HIsViaInterceptor; |
2798 bool dataEquals(HIs other) { | 2798 bool dataEquals(HIs other) { |
2799 return typeExpression == other.typeExpression; | 2799 return typeExpression == other.typeExpression; |
2800 } | 2800 } |
2801 } | 2801 } |
2802 | 2802 |
2803 class HTypeConversion extends HCheck { | 2803 class HTypeConversion extends HCheck { |
2804 final DartType typeExpression; | 2804 // Values for [kind]. |
2805 final int kind; | |
2806 final Selector receiverTypeCheckSelector; | |
2807 final bool contextIsTypeArguments; | |
2808 TypeMask checkedType; // Not final because we refine it. | |
2809 | |
2810 static const int CHECKED_MODE_CHECK = 0; | 2805 static const int CHECKED_MODE_CHECK = 0; |
2811 static const int ARGUMENT_TYPE_CHECK = 1; | 2806 static const int ARGUMENT_TYPE_CHECK = 1; |
2812 static const int CAST_TYPE_CHECK = 2; | 2807 static const int CAST_TYPE_CHECK = 2; |
2813 static const int BOOLEAN_CONVERSION_CHECK = 3; | 2808 static const int BOOLEAN_CONVERSION_CHECK = 3; |
2814 static const int RECEIVER_TYPE_CHECK = 4; | 2809 static const int RECEIVER_TYPE_CHECK = 4; |
2815 | 2810 |
| 2811 final DartType typeExpression; |
| 2812 final int kind; |
| 2813 // [receiverTypeCheckSelector] is the selector used for a receiver type check |
| 2814 // on open-coded operators, e.g. the not-null check on `x` in `x + 1` would be |
| 2815 // compiled to the following, for which we need the selector `$add`. |
| 2816 // |
| 2817 // if (typeof x != "number") x.$add(); |
| 2818 // |
| 2819 final Selector receiverTypeCheckSelector; |
| 2820 |
| 2821 TypeMask checkedType; // Not final because we refine it. |
| 2822 |
2816 HTypeConversion( | 2823 HTypeConversion( |
2817 this.typeExpression, this.kind, TypeMask type, HInstruction input, | 2824 this.typeExpression, this.kind, TypeMask type, HInstruction input, |
2818 [this.receiverTypeCheckSelector]) | 2825 {this.receiverTypeCheckSelector}) |
2819 : contextIsTypeArguments = false, | 2826 : checkedType = type, |
2820 checkedType = type, | |
2821 super(<HInstruction>[input], type) { | 2827 super(<HInstruction>[input], type) { |
2822 assert(!isReceiverTypeCheck || receiverTypeCheckSelector != null); | 2828 assert(!isReceiverTypeCheck || receiverTypeCheckSelector != null); |
2823 assert(typeExpression == null || typeExpression.kind != TypeKind.TYPEDEF); | 2829 assert(typeExpression == null || typeExpression.kind != TypeKind.TYPEDEF); |
2824 sourceElement = input.sourceElement; | 2830 sourceElement = input.sourceElement; |
2825 } | 2831 } |
2826 | 2832 |
2827 HTypeConversion.withTypeRepresentation(this.typeExpression, this.kind, | 2833 HTypeConversion.withTypeRepresentation(this.typeExpression, this.kind, |
2828 TypeMask type, HInstruction input, HInstruction typeRepresentation) | 2834 TypeMask type, HInstruction input, HInstruction typeRepresentation) |
2829 : contextIsTypeArguments = false, | 2835 : checkedType = type, |
2830 checkedType = type, | |
2831 super(<HInstruction>[input, typeRepresentation], type), | 2836 super(<HInstruction>[input, typeRepresentation], type), |
2832 receiverTypeCheckSelector = null { | 2837 receiverTypeCheckSelector = null { |
2833 assert(typeExpression.kind != TypeKind.TYPEDEF); | 2838 assert(typeExpression.kind != TypeKind.TYPEDEF); |
2834 sourceElement = input.sourceElement; | 2839 sourceElement = input.sourceElement; |
2835 } | 2840 } |
2836 | 2841 |
2837 HTypeConversion.withContext(this.typeExpression, this.kind, TypeMask type, | 2842 HTypeConversion.viaMethodOnType(this.typeExpression, this.kind, TypeMask type, |
2838 HInstruction input, HInstruction context, | 2843 HInstruction reifiedType, HInstruction input) |
2839 {bool this.contextIsTypeArguments}) | 2844 : checkedType = type, |
2840 : super(<HInstruction>[input, context], type), | 2845 super(<HInstruction>[reifiedType, input], type), |
2841 checkedType = type, | |
2842 receiverTypeCheckSelector = null { | 2846 receiverTypeCheckSelector = null { |
2843 assert(typeExpression.kind != TypeKind.TYPEDEF); | 2847 // This form is currently used only for function types. |
| 2848 assert(typeExpression.isFunctionType); |
| 2849 assert(kind == CHECKED_MODE_CHECK || kind == CAST_TYPE_CHECK); |
2844 sourceElement = input.sourceElement; | 2850 sourceElement = input.sourceElement; |
2845 } | 2851 } |
2846 | 2852 |
2847 bool get hasTypeRepresentation { | 2853 bool get hasTypeRepresentation { |
2848 return typeExpression.isInterfaceType && inputs.length > 1; | 2854 return typeExpression.isInterfaceType && inputs.length > 1; |
2849 } | 2855 } |
2850 | 2856 |
2851 HInstruction get typeRepresentation => inputs[1]; | 2857 HInstruction get typeRepresentation => inputs[1]; |
2852 | 2858 |
2853 bool get hasContext { | 2859 bool get usesMethodOnType => |
2854 return typeExpression.isFunctionType && inputs.length > 1; | 2860 typeExpression != null && typeExpression.isFunctionType; |
2855 } | |
2856 | 2861 |
2857 HInstruction get context => inputs[1]; | 2862 HInstruction get checkedInput => |
| 2863 usesMethodOnType ? inputs[1] : super.checkedInput; |
2858 | 2864 |
2859 HInstruction convertType(Compiler compiler, DartType type, int kind) { | 2865 HInstruction convertType(Compiler compiler, DartType type, int kind) { |
2860 if (typeExpression == type) { | 2866 if (typeExpression == type) { |
2861 // Don't omit a boolean conversion (which doesn't allow `null`) unless | 2867 // Don't omit a boolean conversion (which doesn't allow `null`) unless |
2862 // this type conversion is already a boolean conversion. | 2868 // this type conversion is already a boolean conversion. |
2863 if (kind != BOOLEAN_CONVERSION_CHECK || isBooleanConversionCheck) { | 2869 if (kind != BOOLEAN_CONVERSION_CHECK || isBooleanConversionCheck) { |
2864 return this; | 2870 return this; |
2865 } | 2871 } |
2866 } | 2872 } |
2867 return super.convertType(compiler, type, kind); | 2873 return super.convertType(compiler, type, kind); |
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3474 class HDynamicType extends HRuntimeType { | 3480 class HDynamicType extends HRuntimeType { |
3475 HDynamicType(DynamicType dartType, TypeMask instructionType) | 3481 HDynamicType(DynamicType dartType, TypeMask instructionType) |
3476 : super(const <HInstruction>[], dartType, instructionType); | 3482 : super(const <HInstruction>[], dartType, instructionType); |
3477 | 3483 |
3478 accept(HVisitor visitor) => visitor.visitDynamicType(this); | 3484 accept(HVisitor visitor) => visitor.visitDynamicType(this); |
3479 | 3485 |
3480 int typeCode() => HInstruction.DYNAMIC_TYPE_TYPECODE; | 3486 int typeCode() => HInstruction.DYNAMIC_TYPE_TYPECODE; |
3481 | 3487 |
3482 bool typeEquals(HInstruction other) => other is HDynamicType; | 3488 bool typeEquals(HInstruction other) => other is HDynamicType; |
3483 } | 3489 } |
OLD | NEW |