| 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 'cps_ir_nodes_sexpr.dart'; | 8 import 'cps_ir_nodes_sexpr.dart'; |
| 9 import '../constants/values.dart' as values; | 9 import '../constants/values.dart' as values; |
| 10 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; | 10 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 /// continuation to invoke when returning from the function. | 416 /// continuation to invoke when returning from the function. |
| 417 class FunctionDefinition extends InteriorNode { | 417 class FunctionDefinition extends InteriorNode { |
| 418 final ExecutableElement element; | 418 final ExecutableElement element; |
| 419 Parameter interceptorParameter; | 419 Parameter interceptorParameter; |
| 420 final Parameter receiverParameter; | 420 final Parameter receiverParameter; |
| 421 final List<Parameter> parameters; | 421 final List<Parameter> parameters; |
| 422 final Continuation returnContinuation; | 422 final Continuation returnContinuation; |
| 423 final SourceInformation sourceInformation; | 423 final SourceInformation sourceInformation; |
| 424 Expression body; | 424 Expression body; |
| 425 | 425 |
| 426 FunctionDefinition( | 426 FunctionDefinition(this.element, this.receiverParameter, this.parameters, |
| 427 this.element, | 427 this.returnContinuation, this.body, |
| 428 this.receiverParameter, | 428 {this.interceptorParameter, this.sourceInformation}); |
| 429 this.parameters, | |
| 430 this.returnContinuation, | |
| 431 this.body, | |
| 432 {this.interceptorParameter, | |
| 433 this.sourceInformation}); | |
| 434 | 429 |
| 435 accept(BlockVisitor visitor) => visitor.visitFunctionDefinition(this); | 430 accept(BlockVisitor visitor) => visitor.visitFunctionDefinition(this); |
| 436 | 431 |
| 437 void setParentPointers() { | 432 void setParentPointers() { |
| 438 if (interceptorParameter != null) interceptorParameter.parent = this; | 433 if (interceptorParameter != null) interceptorParameter.parent = this; |
| 439 if (receiverParameter != null) receiverParameter.parent = this; | 434 if (receiverParameter != null) receiverParameter.parent = this; |
| 440 _setParentsOnNodes(parameters, this); | 435 _setParentsOnNodes(parameters, this); |
| 441 returnContinuation.parent = this; | 436 returnContinuation.parent = this; |
| 442 if (body != null) body.parent = this; | 437 if (body != null) body.parent = this; |
| 443 } | 438 } |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 TypeMask mask; | 556 TypeMask mask; |
| 562 final List<Reference<Primitive>> argumentRefs; | 557 final List<Reference<Primitive>> argumentRefs; |
| 563 final SourceInformation sourceInformation; | 558 final SourceInformation sourceInformation; |
| 564 CallingConvention _callingConvention; | 559 CallingConvention _callingConvention; |
| 565 | 560 |
| 566 CallingConvention get callingConvention => _callingConvention; | 561 CallingConvention get callingConvention => _callingConvention; |
| 567 | 562 |
| 568 InvokeMethod( | 563 InvokeMethod( |
| 569 Primitive receiver, this.selector, this.mask, List<Primitive> arguments, | 564 Primitive receiver, this.selector, this.mask, List<Primitive> arguments, |
| 570 {this.sourceInformation, | 565 {this.sourceInformation, |
| 571 CallingConvention callingConvention, | 566 CallingConvention callingConvention, |
| 572 Primitive interceptor}) | 567 Primitive interceptor}) |
| 573 : this.receiverRef = new Reference<Primitive>(receiver), | 568 : this.receiverRef = new Reference<Primitive>(receiver), |
| 574 this.argumentRefs = _referenceList(arguments), | 569 this.argumentRefs = _referenceList(arguments), |
| 575 this.interceptorRef = _optionalReference(interceptor), | 570 this.interceptorRef = _optionalReference(interceptor), |
| 576 this._callingConvention = callingConvention ?? | 571 this._callingConvention = callingConvention ?? |
| 577 (interceptor != null | 572 (interceptor != null |
| 578 ? CallingConvention.Intercepted | 573 ? CallingConvention.Intercepted |
| 579 : CallingConvention.Normal); | 574 : CallingConvention.Normal); |
| 580 | 575 |
| 581 accept(Visitor visitor) => visitor.visitInvokeMethod(this); | 576 accept(Visitor visitor) => visitor.visitInvokeMethod(this); |
| 582 | 577 |
| (...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1137 /// | 1132 /// |
| 1138 /// { [variable] := [value]; [body] } | 1133 /// { [variable] := [value]; [body] } |
| 1139 class SetMutable extends Primitive { | 1134 class SetMutable extends Primitive { |
| 1140 final Reference<MutableVariable> variableRef; | 1135 final Reference<MutableVariable> variableRef; |
| 1141 final Reference<Primitive> valueRef; | 1136 final Reference<Primitive> valueRef; |
| 1142 final SourceInformation sourceInformation; | 1137 final SourceInformation sourceInformation; |
| 1143 | 1138 |
| 1144 MutableVariable get variable => variableRef.definition; | 1139 MutableVariable get variable => variableRef.definition; |
| 1145 Primitive get value => valueRef.definition; | 1140 Primitive get value => valueRef.definition; |
| 1146 | 1141 |
| 1147 SetMutable( | 1142 SetMutable(MutableVariable variable, Primitive value, |
| 1148 MutableVariable variable, | |
| 1149 Primitive value, | |
| 1150 {this.sourceInformation}) | 1143 {this.sourceInformation}) |
| 1151 : this.variableRef = new Reference<MutableVariable>(variable), | 1144 : this.variableRef = new Reference<MutableVariable>(variable), |
| 1152 this.valueRef = new Reference<Primitive>(value); | 1145 this.valueRef = new Reference<Primitive>(value); |
| 1153 | 1146 |
| 1154 accept(Visitor visitor) => visitor.visitSetMutable(this); | 1147 accept(Visitor visitor) => visitor.visitSetMutable(this); |
| 1155 | 1148 |
| 1156 bool get hasValue => false; | 1149 bool get hasValue => false; |
| 1157 bool get isSafeForElimination => false; | 1150 bool get isSafeForElimination => false; |
| 1158 bool get isSafeForReordering => false; | 1151 bool get isSafeForReordering => false; |
| 1159 | 1152 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1174 /// True if the field never changes value. | 1167 /// True if the field never changes value. |
| 1175 final bool isFinal; | 1168 final bool isFinal; |
| 1176 | 1169 |
| 1177 /// True if the object is known not to be null. | 1170 /// True if the object is known not to be null. |
| 1178 // TODO(asgerf): This is a placeholder until we agree on how to track | 1171 // TODO(asgerf): This is a placeholder until we agree on how to track |
| 1179 // side effects. | 1172 // side effects. |
| 1180 bool objectIsNotNull = false; | 1173 bool objectIsNotNull = false; |
| 1181 | 1174 |
| 1182 Primitive get object => objectRef.definition; | 1175 Primitive get object => objectRef.definition; |
| 1183 | 1176 |
| 1184 GetField( | 1177 GetField(Primitive object, this.field, |
| 1185 Primitive object, | 1178 {this.sourceInformation, this.isFinal: false}) |
| 1186 this.field, | |
| 1187 {this.sourceInformation, | |
| 1188 this.isFinal: false}) | |
| 1189 : this.objectRef = new Reference<Primitive>(object); | 1179 : this.objectRef = new Reference<Primitive>(object); |
| 1190 | 1180 |
| 1191 accept(Visitor visitor) => visitor.visitGetField(this); | 1181 accept(Visitor visitor) => visitor.visitGetField(this); |
| 1192 | 1182 |
| 1193 bool get hasValue => true; | 1183 bool get hasValue => true; |
| 1194 bool get isSafeForElimination => objectIsNotNull; | 1184 bool get isSafeForElimination => objectIsNotNull; |
| 1195 bool get isSafeForReordering => false; | 1185 bool get isSafeForReordering => false; |
| 1196 | 1186 |
| 1197 toString() => 'GetField($field)'; | 1187 toString() => 'GetField($field)'; |
| 1198 | 1188 |
| 1199 void setParentPointers() { | 1189 void setParentPointers() { |
| 1200 objectRef.parent = this; | 1190 objectRef.parent = this; |
| 1201 } | 1191 } |
| 1202 | 1192 |
| 1203 int get effects => isFinal ? 0 : Effects.dependsOnInstanceField; | 1193 int get effects => isFinal ? 0 : Effects.dependsOnInstanceField; |
| 1204 } | 1194 } |
| 1205 | 1195 |
| 1206 /// Directly assigns to a field on a given object. | 1196 /// Directly assigns to a field on a given object. |
| 1207 class SetField extends Primitive { | 1197 class SetField extends Primitive { |
| 1208 final Reference<Primitive> objectRef; | 1198 final Reference<Primitive> objectRef; |
| 1209 FieldElement field; | 1199 FieldElement field; |
| 1210 final Reference<Primitive> valueRef; | 1200 final Reference<Primitive> valueRef; |
| 1211 final SourceInformation sourceInformation; | 1201 final SourceInformation sourceInformation; |
| 1212 | 1202 |
| 1213 Primitive get object => objectRef.definition; | 1203 Primitive get object => objectRef.definition; |
| 1214 Primitive get value => valueRef.definition; | 1204 Primitive get value => valueRef.definition; |
| 1215 | 1205 |
| 1216 SetField( | 1206 SetField(Primitive object, this.field, Primitive value, |
| 1217 Primitive object, | |
| 1218 this.field, | |
| 1219 Primitive value, | |
| 1220 {this.sourceInformation}) | 1207 {this.sourceInformation}) |
| 1221 : this.objectRef = new Reference<Primitive>(object), | 1208 : this.objectRef = new Reference<Primitive>(object), |
| 1222 this.valueRef = new Reference<Primitive>(value); | 1209 this.valueRef = new Reference<Primitive>(value); |
| 1223 | 1210 |
| 1224 accept(Visitor visitor) => visitor.visitSetField(this); | 1211 accept(Visitor visitor) => visitor.visitSetField(this); |
| 1225 | 1212 |
| 1226 bool get hasValue => false; | 1213 bool get hasValue => false; |
| 1227 bool get isSafeForElimination => false; | 1214 bool get isSafeForElimination => false; |
| 1228 bool get isSafeForReordering => false; | 1215 bool get isSafeForReordering => false; |
| 1229 | 1216 |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1541 final js.Template codeTemplate; | 1528 final js.Template codeTemplate; |
| 1542 final TypeMask storedType; | 1529 final TypeMask storedType; |
| 1543 final List<Reference<Primitive>> argumentRefs; | 1530 final List<Reference<Primitive>> argumentRefs; |
| 1544 final native.NativeBehavior nativeBehavior; | 1531 final native.NativeBehavior nativeBehavior; |
| 1545 final SourceInformation sourceInformation; | 1532 final SourceInformation sourceInformation; |
| 1546 final FunctionElement dependency; | 1533 final FunctionElement dependency; |
| 1547 | 1534 |
| 1548 Primitive argument(int n) => argumentRefs[n].definition; | 1535 Primitive argument(int n) => argumentRefs[n].definition; |
| 1549 Iterable<Primitive> get arguments => _dereferenceList(argumentRefs); | 1536 Iterable<Primitive> get arguments => _dereferenceList(argumentRefs); |
| 1550 | 1537 |
| 1551 ForeignCode( | 1538 ForeignCode(this.codeTemplate, this.storedType, List<Primitive> arguments, |
| 1552 this.codeTemplate, | 1539 this.nativeBehavior, this.sourceInformation, |
| 1553 this.storedType, | |
| 1554 List<Primitive> arguments, | |
| 1555 this.nativeBehavior, | |
| 1556 this.sourceInformation, | |
| 1557 {this.dependency}) | 1540 {this.dependency}) |
| 1558 : this.argumentRefs = _referenceList(arguments) { | 1541 : this.argumentRefs = _referenceList(arguments) { |
| 1559 effects = Effects.from(nativeBehavior.sideEffects); | 1542 effects = Effects.from(nativeBehavior.sideEffects); |
| 1560 } | 1543 } |
| 1561 | 1544 |
| 1562 accept(Visitor visitor) => visitor.visitForeignCode(this); | 1545 accept(Visitor visitor) => visitor.visitForeignCode(this); |
| 1563 | 1546 |
| 1564 bool get hasValue => true; | 1547 bool get hasValue => true; |
| 1565 | 1548 |
| 1566 void setParentPointers() { | 1549 void setParentPointers() { |
| (...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2077 Continuation get trueContinuation => trueContinuationRef.definition; | 2060 Continuation get trueContinuation => trueContinuationRef.definition; |
| 2078 Continuation get falseContinuation => falseContinuationRef.definition; | 2061 Continuation get falseContinuation => falseContinuationRef.definition; |
| 2079 | 2062 |
| 2080 /// If true, only the value `true` satisfies the condition. Otherwise, any | 2063 /// If true, only the value `true` satisfies the condition. Otherwise, any |
| 2081 /// truthy value satisfies the check. | 2064 /// truthy value satisfies the check. |
| 2082 /// | 2065 /// |
| 2083 /// Non-strict checks are preferable when the condition is known to be a | 2066 /// Non-strict checks are preferable when the condition is known to be a |
| 2084 /// boolean. | 2067 /// boolean. |
| 2085 bool isStrictCheck; | 2068 bool isStrictCheck; |
| 2086 | 2069 |
| 2087 Branch( | 2070 Branch(Primitive condition, Continuation trueCont, Continuation falseCont, |
| 2088 Primitive condition, | |
| 2089 Continuation trueCont, | |
| 2090 Continuation falseCont, | |
| 2091 this.sourceInformation, | 2071 this.sourceInformation, |
| 2092 {bool strict}) | 2072 {bool strict}) |
| 2093 : this.conditionRef = new Reference<Primitive>(condition), | 2073 : this.conditionRef = new Reference<Primitive>(condition), |
| 2094 trueContinuationRef = new Reference<Continuation>(trueCont), | 2074 trueContinuationRef = new Reference<Continuation>(trueCont), |
| 2095 falseContinuationRef = new Reference<Continuation>(falseCont), | 2075 falseContinuationRef = new Reference<Continuation>(falseCont), |
| 2096 isStrictCheck = strict { | 2076 isStrictCheck = strict { |
| 2097 assert(strict != null); | 2077 assert(strict != null); |
| 2098 } | 2078 } |
| 2099 | 2079 |
| 2100 Branch.strict( | 2080 Branch.strict(Primitive condition, Continuation trueCont, |
| 2101 Primitive condition, | 2081 Continuation falseCont, SourceInformation sourceInformation) |
| 2102 Continuation trueCont, | |
| 2103 Continuation falseCont, | |
| 2104 SourceInformation sourceInformation) | |
| 2105 : this(condition, trueCont, falseCont, sourceInformation, strict: true); | 2082 : this(condition, trueCont, falseCont, sourceInformation, strict: true); |
| 2106 | 2083 |
| 2107 Branch.loose( | 2084 Branch.loose(Primitive condition, Continuation trueCont, |
| 2108 Primitive condition, | 2085 Continuation falseCont, SourceInformation sourceInformation) |
| 2109 Continuation trueCont, | |
| 2110 Continuation falseCont, | |
| 2111 SourceInformation sourceInformation) | |
| 2112 : this(condition, trueCont, falseCont, sourceInformation, strict: false); | 2086 : this(condition, trueCont, falseCont, sourceInformation, strict: false); |
| 2113 | 2087 |
| 2114 accept(BlockVisitor visitor) => visitor.visitBranch(this); | 2088 accept(BlockVisitor visitor) => visitor.visitBranch(this); |
| 2115 | 2089 |
| 2116 void setParentPointers() { | 2090 void setParentPointers() { |
| 2117 conditionRef.parent = this; | 2091 conditionRef.parent = this; |
| 2118 trueContinuationRef.parent = this; | 2092 trueContinuationRef.parent = this; |
| 2119 falseContinuationRef.parent = this; | 2093 falseContinuationRef.parent = this; |
| 2120 } | 2094 } |
| 2121 } | 2095 } |
| (...skipping 759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2881 Definition visitLiteralList(LiteralList node) { | 2855 Definition visitLiteralList(LiteralList node) { |
| 2882 return new LiteralList(node.dartType, getList(node.valueRefs)) | 2856 return new LiteralList(node.dartType, getList(node.valueRefs)) |
| 2883 ..allocationSiteType = node.allocationSiteType; | 2857 ..allocationSiteType = node.allocationSiteType; |
| 2884 } | 2858 } |
| 2885 | 2859 |
| 2886 Definition visitConstant(Constant node) { | 2860 Definition visitConstant(Constant node) { |
| 2887 return new Constant(node.value, sourceInformation: node.sourceInformation); | 2861 return new Constant(node.value, sourceInformation: node.sourceInformation); |
| 2888 } | 2862 } |
| 2889 | 2863 |
| 2890 Definition visitGetMutable(GetMutable node) { | 2864 Definition visitGetMutable(GetMutable node) { |
| 2891 return new GetMutable( | 2865 return new GetMutable(getCopy(node.variableRef), |
| 2892 getCopy(node.variableRef), sourceInformation: node.sourceInformation); | 2866 sourceInformation: node.sourceInformation); |
| 2893 } | 2867 } |
| 2894 | 2868 |
| 2895 Definition visitParameter(Parameter node) { | 2869 Definition visitParameter(Parameter node) { |
| 2896 return new Parameter(node.hint); | 2870 return new Parameter(node.hint); |
| 2897 } | 2871 } |
| 2898 | 2872 |
| 2899 Definition visitMutableVariable(MutableVariable node) { | 2873 Definition visitMutableVariable(MutableVariable node) { |
| 2900 return new MutableVariable(node.hint); | 2874 return new MutableVariable(node.hint); |
| 2901 } | 2875 } |
| 2902 | 2876 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2997 Definition visitReceiverCheck(ReceiverCheck node) { | 2971 Definition visitReceiverCheck(ReceiverCheck node) { |
| 2998 return new ReceiverCheck( | 2972 return new ReceiverCheck( |
| 2999 getCopy(node.valueRef), node.selector, node.sourceInformation, | 2973 getCopy(node.valueRef), node.selector, node.sourceInformation, |
| 3000 condition: getCopyOrNull(node.conditionRef), | 2974 condition: getCopyOrNull(node.conditionRef), |
| 3001 useSelector: node.useSelector, | 2975 useSelector: node.useSelector, |
| 3002 isNullCheck: node.isNullCheck); | 2976 isNullCheck: node.isNullCheck); |
| 3003 } | 2977 } |
| 3004 | 2978 |
| 3005 Definition visitForeignCode(ForeignCode node) { | 2979 Definition visitForeignCode(ForeignCode node) { |
| 3006 return new ForeignCode(node.codeTemplate, node.storedType, | 2980 return new ForeignCode(node.codeTemplate, node.storedType, |
| 3007 getList(node.argumentRefs), node.nativeBehavior, | 2981 getList(node.argumentRefs), node.nativeBehavior, node.sourceInformation, |
| 3008 node.sourceInformation, | |
| 3009 dependency: node.dependency); | 2982 dependency: node.dependency); |
| 3010 } | 2983 } |
| 3011 } | 2984 } |
| 3012 | 2985 |
| 3013 /// A trampolining visitor to copy [FunctionDefinition]s. | 2986 /// A trampolining visitor to copy [FunctionDefinition]s. |
| 3014 class CopyingVisitor extends TrampolineRecursiveVisitor { | 2987 class CopyingVisitor extends TrampolineRecursiveVisitor { |
| 3015 // The visitor maintains a map from original continuations to their copies. | 2988 // The visitor maintains a map from original continuations to their copies. |
| 3016 Map<Continuation, Continuation> _copies = <Continuation, Continuation>{}; | 2989 Map<Continuation, Continuation> _copies = <Continuation, Continuation>{}; |
| 3017 | 2990 |
| 3018 // The visitor uses an auxiliary visitor to copy definitions. | 2991 // The visitor uses an auxiliary visitor to copy definitions. |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3145 _definitions.getCopy(node.conditionRef), | 3118 _definitions.getCopy(node.conditionRef), |
| 3146 _copies[node.trueContinuation], | 3119 _copies[node.trueContinuation], |
| 3147 _copies[node.falseContinuation], | 3120 _copies[node.falseContinuation], |
| 3148 node.sourceInformation)..isStrictCheck = node.isStrictCheck); | 3121 node.sourceInformation)..isStrictCheck = node.isStrictCheck); |
| 3149 } | 3122 } |
| 3150 | 3123 |
| 3151 visitUnreachable(Unreachable node) { | 3124 visitUnreachable(Unreachable node) { |
| 3152 plug(new Unreachable()); | 3125 plug(new Unreachable()); |
| 3153 } | 3126 } |
| 3154 } | 3127 } |
| OLD | NEW |