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 |