Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart

Issue 1507313006: dart2js cps: Add instruction for null checks. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fix true/false misdocumentation about condition and do not emit call Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 '../constants/values.dart' as values; 7 import '../constants/values.dart' as values;
8 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; 8 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType;
9 import '../elements/elements.dart'; 9 import '../elements/elements.dart';
10 import '../io/source_information.dart' show SourceInformation; 10 import '../io/source_information.dart' show SourceInformation;
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 bool get isSafeForElimination; 227 bool get isSafeForElimination;
228 228
229 /// True if time-of-evaluation is irrelevant for the given primitive, 229 /// True if time-of-evaluation is irrelevant for the given primitive,
230 /// assuming its inputs are the same values. 230 /// assuming its inputs are the same values.
231 bool get isSafeForReordering; 231 bool get isSafeForReordering;
232 232
233 /// The source information associated with this primitive. 233 /// The source information associated with this primitive.
234 // TODO(johnniwinther): Require source information for all primitives. 234 // TODO(johnniwinther): Require source information for all primitives.
235 SourceInformation get sourceInformation => null; 235 SourceInformation get sourceInformation => null;
236 236
237 /// If this is a [Refinement] node, returns the value being refined. 237 /// If this is a [Refinement], [BoundsCheck] or [NullCheck] node, returns the
238 /// value being refined, the indexable object being checked, or the value
239 /// that was checked to be non-null, respectively.
240 ///
241 /// Those instructions all return the corresponding operand directly, and
242 /// this getter can be used to get (closer to) where the value came from.
243 //
244 // TODO(asgerf): Also do this for [TypeCast]?
238 Primitive get effectiveDefinition => this; 245 Primitive get effectiveDefinition => this;
239 246
240 /// True if the two primitives are (refinements of) the same value. 247 /// True if the two primitives are (refinements of) the same value.
241 bool sameValue(Primitive other) { 248 bool sameValue(Primitive other) {
242 return effectiveDefinition == other.effectiveDefinition; 249 return effectiveDefinition == other.effectiveDefinition;
243 } 250 }
244 251
245 /// Iterates all non-refinement uses of the primitive and all uses of 252 /// Iterates all non-refinement uses of the primitive and all uses of
246 /// a [Refinement] of this primitive (transitively). 253 /// a [Refinement] of this primitive (transitively).
247 /// 254 ///
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 704
698 accept(Visitor visitor) => visitor.visitRefinement(this); 705 accept(Visitor visitor) => visitor.visitRefinement(this);
699 706
700 Primitive get effectiveDefinition => value.definition.effectiveDefinition; 707 Primitive get effectiveDefinition => value.definition.effectiveDefinition;
701 708
702 void setParentPointers() { 709 void setParentPointers() {
703 value.parent = this; 710 value.parent = this;
704 } 711 }
705 } 712 }
706 713
714 /// Throw an exception if [value] is `null`.
715 ///
716 /// Returns [value] so this can be used to restrict code motion.
717 ///
718 /// In the simplest form this compiles to `value.toString;`.
719 ///
720 /// If [selector] is set, `toString` is replaced with the (possibly minified)
721 /// invocation name of the selector. This can be shorter and generate a more
722 /// meaningful error message, but is expensive if [value] is non-null and does
723 /// not have that property at runtime.
724 ///
725 /// If [condition] is set, it is assumed that [condition] is true if and only
726 /// if [value] is null. The check then compiles to:
727 ///
728 /// if (condition) value.toString; (or .selector if non-null)
729 ///
730 /// The latter form is useful when [condition] is a form understood by the JS
731 /// runtime, such as a `typeof` test.
732 class NullCheck extends Primitive {
733 final Reference<Primitive> value;
734 Selector selector;
735 Reference<Primitive> condition;
736 final SourceInformation sourceInformation;
737
738 NullCheck(Primitive value, this.sourceInformation)
739 : this.value = new Reference<Primitive>(value);
740
741 NullCheck.guarded(Primitive condition, Primitive value, this.selector,
742 this.sourceInformation)
743 : this.condition = new Reference<Primitive>(condition),
744 this.value = new Reference<Primitive>(value);
745
746 bool get isSafeForElimination => false;
747 bool get isSafeForReordering => false;
748 bool get hasValue => true;
749
750 accept(Visitor visitor) => visitor.visitNullCheck(this);
751
752 void setParentPointers() {
753 value.parent = this;
754 if (condition != null) {
755 condition.parent = this;
756 }
757 }
758
759 Primitive get effectiveDefinition => value.definition.effectiveDefinition;
760 }
761
707 /// An "is" type test. 762 /// An "is" type test.
708 /// 763 ///
709 /// Returns `true` if [value] is an instance of [type]. 764 /// Returns `true` if [value] is an instance of [type].
710 /// 765 ///
711 /// [type] must not be the [Object], `dynamic` or [Null] types (though it might 766 /// [type] must not be the [Object], `dynamic` or [Null] types (though it might
712 /// be a type variable containing one of these types). This design is chosen 767 /// be a type variable containing one of these types). This design is chosen
713 /// to simplify code generation for type tests. 768 /// to simplify code generation for type tests.
714 class TypeTest extends Primitive { 769 class TypeTest extends Primitive {
715 Reference<Primitive> value; 770 Reference<Primitive> value;
716 final DartType dartType; 771 final DartType dartType;
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
1086 bool get isSafeForElimination => objectIsNotNull; 1141 bool get isSafeForElimination => objectIsNotNull;
1087 bool get isSafeForReordering => false; 1142 bool get isSafeForReordering => false;
1088 1143
1089 accept(Visitor v) => v.visitGetLength(this); 1144 accept(Visitor v) => v.visitGetLength(this);
1090 1145
1091 void setParentPointers() { 1146 void setParentPointers() {
1092 object.parent = this; 1147 object.parent = this;
1093 } 1148 }
1094 } 1149 }
1095 1150
1096 /// Read an entry from a string or native list. 1151 /// Read an entry from an indexable object.
1097 /// 1152 ///
1098 /// [object] must be null or a native list or a string, and [index] must be 1153 /// [object] must be null or an indexable object, and [index] must be
1099 /// an integer. 1154 /// an integer where `0 <= index < object.length`.
1100 class GetIndex extends Primitive { 1155 class GetIndex extends Primitive {
1101 final Reference<Primitive> object; 1156 final Reference<Primitive> object;
1102 final Reference<Primitive> index; 1157 final Reference<Primitive> index;
1103 1158
1104 /// True if the object is known not to be null. 1159 /// True if the object is known not to be null.
1105 bool objectIsNotNull = false; 1160 bool objectIsNotNull = false;
1106 1161
1107 GetIndex(Primitive object, Primitive index) 1162 GetIndex(Primitive object, Primitive index)
1108 : this.object = new Reference<Primitive>(object), 1163 : this.object = new Reference<Primitive>(object),
1109 this.index = new Reference<Primitive>(index); 1164 this.index = new Reference<Primitive>(index);
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
1725 T visitTypeExpression(TypeExpression node); 1780 T visitTypeExpression(TypeExpression node);
1726 T visitCreateInvocationMirror(CreateInvocationMirror node); 1781 T visitCreateInvocationMirror(CreateInvocationMirror node);
1727 T visitTypeTest(TypeTest node); 1782 T visitTypeTest(TypeTest node);
1728 T visitTypeTestViaFlag(TypeTestViaFlag node); 1783 T visitTypeTestViaFlag(TypeTestViaFlag node);
1729 T visitApplyBuiltinOperator(ApplyBuiltinOperator node); 1784 T visitApplyBuiltinOperator(ApplyBuiltinOperator node);
1730 T visitApplyBuiltinMethod(ApplyBuiltinMethod node); 1785 T visitApplyBuiltinMethod(ApplyBuiltinMethod node);
1731 T visitGetLength(GetLength node); 1786 T visitGetLength(GetLength node);
1732 T visitGetIndex(GetIndex node); 1787 T visitGetIndex(GetIndex node);
1733 T visitSetIndex(SetIndex node); 1788 T visitSetIndex(SetIndex node);
1734 T visitRefinement(Refinement node); 1789 T visitRefinement(Refinement node);
1790 T visitNullCheck(NullCheck node);
1735 1791
1736 // Support for literal foreign code. 1792 // Support for literal foreign code.
1737 T visitForeignCode(ForeignCode node); 1793 T visitForeignCode(ForeignCode node);
1738 } 1794 }
1739 1795
1740 /// Recursively visits all children of a CPS term. 1796 /// Recursively visits all children of a CPS term.
1741 /// 1797 ///
1742 /// The user of the class is responsible for avoiding stack overflows from 1798 /// The user of the class is responsible for avoiding stack overflows from
1743 /// deep recursion, e.g. by overriding methods to cut off recursion at certain 1799 /// deep recursion, e.g. by overriding methods to cut off recursion at certain
1744 /// points. 1800 /// points.
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
2043 processReference(node.object); 2099 processReference(node.object);
2044 processReference(node.index); 2100 processReference(node.index);
2045 processReference(node.value); 2101 processReference(node.value);
2046 } 2102 }
2047 2103
2048 processRefinement(Refinement node) {} 2104 processRefinement(Refinement node) {}
2049 visitRefinement(Refinement node) { 2105 visitRefinement(Refinement node) {
2050 processRefinement(node); 2106 processRefinement(node);
2051 processReference(node.value); 2107 processReference(node.value);
2052 } 2108 }
2109
2110 processNullCheck(NullCheck node) {}
2111 visitNullCheck(NullCheck node) {
2112 processNullCheck(node);
2113 processReference(node.value);
2114 if (node.condition != null) {
2115 processReference(node.condition);
2116 }
2117 }
2053 } 2118 }
2054 2119
2055 typedef void StackAction(); 2120 typedef void StackAction();
2056 2121
2057 /// Calls `process*` for all nodes in a tree. 2122 /// Calls `process*` for all nodes in a tree.
2058 /// For simple usage, only override the `process*` methods. 2123 /// For simple usage, only override the `process*` methods.
2059 /// 2124 ///
2060 /// To avoid deep recursion, this class uses an "action stack" containing 2125 /// To avoid deep recursion, this class uses an "action stack" containing
2061 /// callbacks to be invoked after the processing of some term has finished. 2126 /// callbacks to be invoked after the processing of some term has finished.
2062 /// 2127 ///
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
2176 /// Visit a just-deleted subterm and unlink all [Reference]s in it. 2241 /// Visit a just-deleted subterm and unlink all [Reference]s in it.
2177 class RemovalVisitor extends TrampolineRecursiveVisitor { 2242 class RemovalVisitor extends TrampolineRecursiveVisitor {
2178 processReference(Reference reference) { 2243 processReference(Reference reference) {
2179 reference.unlink(); 2244 reference.unlink();
2180 } 2245 }
2181 2246
2182 static void remove(Node node) { 2247 static void remove(Node node) {
2183 (new RemovalVisitor()).visit(node); 2248 (new RemovalVisitor()).visit(node);
2184 } 2249 }
2185 } 2250 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698