| 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 'cps_fragment.dart' show CpsFragment; | 7 import 'cps_fragment.dart' show CpsFragment; |
| 8 import '../constants/values.dart' as values; | 8 import '../constants/values.dart' as values; |
| 9 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; | 9 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; |
| 10 import '../elements/elements.dart'; | 10 import '../elements/elements.dart'; |
| (...skipping 832 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 843 | 843 |
| 844 Primitive get effectiveDefinition => object.definition.effectiveDefinition; | 844 Primitive get effectiveDefinition => object.definition.effectiveDefinition; |
| 845 } | 845 } |
| 846 | 846 |
| 847 /// Throw an exception if [value] is `null`. | 847 /// Throw an exception if [value] is `null`. |
| 848 /// | 848 /// |
| 849 /// Returns [value] so this can be used to restrict code motion. | 849 /// Returns [value] so this can be used to restrict code motion. |
| 850 /// | 850 /// |
| 851 /// In the simplest form this compiles to `value.toString;`. | 851 /// In the simplest form this compiles to `value.toString;`. |
| 852 /// | 852 /// |
| 853 /// If [selector] is set, `toString` is replaced with the (possibly minified) | 853 /// [selector] holds the selector that is the cause of the null check. This is |
| 854 /// invocation name of the selector. This can be shorter and generate a more | 854 /// usually a method that was inlined where [value] the receiver. |
| 855 /// meaningful error message, but is expensive if [value] is non-null and does | 855 /// |
| 856 /// not have that property at runtime. | 856 /// If [selector] is set and [useSelector] is true, `toString` is replaced with |
| 857 /// the (possibly minified) invocation name of the selector. This can be |
| 858 /// shorter and generate a more meaningful error message, but is expensive if |
| 859 /// [value] is non-null and does not have that property at runtime. |
| 857 /// | 860 /// |
| 858 /// If [condition] is set, it is assumed that [condition] is true if and only | 861 /// If [condition] is set, it is assumed that [condition] is true if and only |
| 859 /// if [value] is null. The check then compiles to: | 862 /// if [value] is null. The check then compiles to: |
| 860 /// | 863 /// |
| 861 /// if (condition) value.toString; (or .selector if non-null) | 864 /// if (condition) value.toString; (or .selector if non-null) |
| 862 /// | 865 /// |
| 863 /// The latter form is useful when [condition] is a form understood by the JS | 866 /// The latter form is useful when [condition] is a form understood by the JS |
| 864 /// runtime, such as a `typeof` test. | 867 /// runtime, such as a `typeof` test. |
| 865 class NullCheck extends Primitive { | 868 class NullCheck extends Primitive { |
| 866 final Reference<Primitive> value; | 869 final Reference<Primitive> value; |
| 867 Selector selector; | 870 final Selector selector; |
| 868 Reference<Primitive> condition; | 871 final bool useSelector; |
| 872 final Reference<Primitive> condition; |
| 869 final SourceInformation sourceInformation; | 873 final SourceInformation sourceInformation; |
| 870 | 874 |
| 871 NullCheck(Primitive value, this.sourceInformation) | 875 NullCheck(Primitive value, this.sourceInformation, |
| 872 : this.value = new Reference<Primitive>(value); | 876 {Primitive condition, |
| 877 this.selector, |
| 878 this.useSelector: false}) |
| 879 : this.value = new Reference<Primitive>(value), |
| 880 this.condition = |
| 881 condition == null ? null : new Reference<Primitive>(condition); |
| 873 | 882 |
| 874 NullCheck.guarded(Primitive condition, Primitive value, this.selector, | 883 NullCheck.guarded(Primitive condition, Primitive value, this.selector, |
| 875 this.sourceInformation) | 884 this.sourceInformation) |
| 876 : this.condition = new Reference<Primitive>(condition), | 885 : this.condition = new Reference<Primitive>(condition), |
| 877 this.value = new Reference<Primitive>(value); | 886 this.value = new Reference<Primitive>(value), |
| 887 this.useSelector = true; |
| 878 | 888 |
| 879 bool get isSafeForElimination => false; | 889 bool get isSafeForElimination => false; |
| 880 bool get isSafeForReordering => false; | 890 bool get isSafeForReordering => false; |
| 881 bool get hasValue => true; | 891 bool get hasValue => true; |
| 882 | 892 |
| 883 accept(Visitor visitor) => visitor.visitNullCheck(this); | 893 accept(Visitor visitor) => visitor.visitNullCheck(this); |
| 884 | 894 |
| 885 void setParentPointers() { | 895 void setParentPointers() { |
| 886 value.parent = this; | 896 value.parent = this; |
| 887 if (condition != null) { | 897 if (condition != null) { |
| (...skipping 1801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2689 node.sourceInformation); | 2699 node.sourceInformation); |
| 2690 } else { | 2700 } else { |
| 2691 return new BoundsCheck(getCopy(node.object), getCopy(node.index), | 2701 return new BoundsCheck(getCopy(node.object), getCopy(node.index), |
| 2692 getCopy(node.length), | 2702 getCopy(node.length), |
| 2693 node.checks, | 2703 node.checks, |
| 2694 node.sourceInformation); | 2704 node.sourceInformation); |
| 2695 } | 2705 } |
| 2696 } | 2706 } |
| 2697 | 2707 |
| 2698 Definition visitNullCheck(NullCheck node) { | 2708 Definition visitNullCheck(NullCheck node) { |
| 2699 return new NullCheck(getCopy(node.value), node.sourceInformation); | 2709 return new NullCheck(getCopy(node.value), node.sourceInformation, |
| 2710 condition: node.condition == null ? null : getCopy(node.condition), |
| 2711 selector: node.selector, |
| 2712 useSelector: node.useSelector); |
| 2700 } | 2713 } |
| 2701 | 2714 |
| 2702 Definition visitForeignCode(ForeignCode node) { | 2715 Definition visitForeignCode(ForeignCode node) { |
| 2703 return new ForeignCode(node.codeTemplate, node.type, | 2716 return new ForeignCode(node.codeTemplate, node.type, |
| 2704 getList(node.arguments), | 2717 getList(node.arguments), |
| 2705 node.nativeBehavior, | 2718 node.nativeBehavior, |
| 2706 dependency: node.dependency); | 2719 dependency: node.dependency); |
| 2707 } | 2720 } |
| 2708 } | 2721 } |
| 2709 | 2722 |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2837 plug(new Branch.loose(_definitions.getCopy(node.condition), | 2850 plug(new Branch.loose(_definitions.getCopy(node.condition), |
| 2838 _copies[node.trueContinuation.definition], | 2851 _copies[node.trueContinuation.definition], |
| 2839 _copies[node.falseContinuation.definition]) | 2852 _copies[node.falseContinuation.definition]) |
| 2840 ..isStrictCheck = node.isStrictCheck); | 2853 ..isStrictCheck = node.isStrictCheck); |
| 2841 } | 2854 } |
| 2842 | 2855 |
| 2843 visitUnreachable(Unreachable node) { | 2856 visitUnreachable(Unreachable node) { |
| 2844 plug(new Unreachable()); | 2857 plug(new Unreachable()); |
| 2845 } | 2858 } |
| 2846 } | 2859 } |
| OLD | NEW |