| 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 interface HVisitor<R> { | 5 interface HVisitor<R> { |
| 6 R visitAdd(HAdd node); | 6 R visitAdd(HAdd node); |
| 7 R visitBailoutTarget(HBailoutTarget node); | 7 R visitBailoutTarget(HBailoutTarget node); |
| 8 R visitBitAnd(HBitAnd node); | 8 R visitBitAnd(HBitAnd node); |
| 9 R visitBitNot(HBitNot node); | 9 R visitBitNot(HBitNot node); |
| 10 R visitBitOr(HBitOr node); | 10 R visitBitOr(HBitOr node); |
| (...skipping 1143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1154 bool isControlFlow() => true; | 1154 bool isControlFlow() => true; |
| 1155 final bool isStatement = true; | 1155 final bool isStatement = true; |
| 1156 } | 1156 } |
| 1157 | 1157 |
| 1158 class HInvoke extends HInstruction { | 1158 class HInvoke extends HInstruction { |
| 1159 /** | 1159 /** |
| 1160 * The first argument must be the target: either an [HStatic] node, or | 1160 * The first argument must be the target: either an [HStatic] node, or |
| 1161 * the receiver of a method-call. The remaining inputs are the arguments | 1161 * the receiver of a method-call. The remaining inputs are the arguments |
| 1162 * to the invocation. | 1162 * to the invocation. |
| 1163 */ | 1163 */ |
| 1164 final Selector selector; | 1164 HInvoke(List<HInstruction> inputs) : super(inputs); |
| 1165 HInvoke(Selector this.selector, List<HInstruction> inputs) : super(inputs); | |
| 1166 static final int ARGUMENTS_OFFSET = 1; | 1165 static final int ARGUMENTS_OFFSET = 1; |
| 1167 | 1166 |
| 1168 // TODO(floitsch): make class abstract instead of adding an abstract method. | 1167 // TODO(floitsch): make class abstract instead of adding an abstract method. |
| 1169 abstract accept(HVisitor visitor); | 1168 abstract accept(HVisitor visitor); |
| 1170 } | 1169 } |
| 1171 | 1170 |
| 1172 class HInvokeDynamic extends HInvoke { | 1171 class HInvokeDynamic extends HInvoke { |
| 1172 final Selector selector; |
| 1173 Element element; | 1173 Element element; |
| 1174 SourceString name; | 1174 SourceString name; |
| 1175 HInvokeDynamic( | 1175 |
| 1176 Selector selector, this.element, this.name, List<HInstruction> inputs) | 1176 HInvokeDynamic(this.selector, this.element, this.name, |
| 1177 : super(selector, inputs); | 1177 List<HInstruction> inputs) : super(inputs); |
| 1178 toString() => 'invoke dynamic: $name'; | 1178 toString() => 'invoke dynamic: $name'; |
| 1179 HInstruction get receiver() => inputs[0]; | 1179 HInstruction get receiver() => inputs[0]; |
| 1180 | 1180 |
| 1181 // TODO(floitsch): make class abstract instead of adding an abstract method. | 1181 // TODO(floitsch): make class abstract instead of adding an abstract method. |
| 1182 abstract accept(HVisitor visitor); | 1182 abstract accept(HVisitor visitor); |
| 1183 } | 1183 } |
| 1184 | 1184 |
| 1185 class HInvokeClosure extends HInvokeDynamic { | 1185 class HInvokeClosure extends HInvokeDynamic { |
| 1186 HInvokeClosure(Selector selector, List<HInstruction> inputs) | 1186 HInvokeClosure(Selector selector, List<HInstruction> inputs) |
| 1187 : super(selector, null, const SourceString('call'), inputs); | 1187 : super(selector, null, const SourceString('call'), inputs); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1218 | 1218 |
| 1219 class HInvokeDynamicSetter extends HInvokeDynamicField { | 1219 class HInvokeDynamicSetter extends HInvokeDynamicField { |
| 1220 HInvokeDynamicSetter(selector, element, name, receiver, value) | 1220 HInvokeDynamicSetter(selector, element, name, receiver, value) |
| 1221 : super(selector, element, name, [receiver, value]); | 1221 : super(selector, element, name, [receiver, value]); |
| 1222 toString() => 'invoke dynamic setter: $name'; | 1222 toString() => 'invoke dynamic setter: $name'; |
| 1223 accept(HVisitor visitor) => visitor.visitInvokeDynamicSetter(this); | 1223 accept(HVisitor visitor) => visitor.visitInvokeDynamicSetter(this); |
| 1224 } | 1224 } |
| 1225 | 1225 |
| 1226 class HInvokeStatic extends HInvoke { | 1226 class HInvokeStatic extends HInvoke { |
| 1227 /** The first input must be the target. */ | 1227 /** The first input must be the target. */ |
| 1228 HInvokeStatic(selector, inputs, [HType knownType = HType.UNKNOWN]) | 1228 HInvokeStatic(inputs, [HType knownType = HType.UNKNOWN]) : super(inputs) { |
| 1229 : super(selector, inputs) { | |
| 1230 guaranteedType = knownType; | 1229 guaranteedType = knownType; |
| 1231 } | 1230 } |
| 1232 | 1231 |
| 1233 toString() => 'invoke static: ${element.name}'; | 1232 toString() => 'invoke static: ${element.name}'; |
| 1234 accept(HVisitor visitor) => visitor.visitInvokeStatic(this); | 1233 accept(HVisitor visitor) => visitor.visitInvokeStatic(this); |
| 1235 Element get element() => target.element; | 1234 Element get element() => target.element; |
| 1236 HStatic get target() => inputs[0]; | 1235 HStatic get target() => inputs[0]; |
| 1237 | 1236 |
| 1238 HType computeDesiredTypeForInput(HInstruction input) { | 1237 HType computeDesiredTypeForInput(HInstruction input) { |
| 1239 // TODO(floitsch): we want the target to be a function. | 1238 // TODO(floitsch): we want the target to be a function. |
| 1240 if (input == target) return HType.UNKNOWN; | 1239 if (input == target) return HType.UNKNOWN; |
| 1241 return computeDesiredTypeForNonTargetInput(input); | 1240 return computeDesiredTypeForNonTargetInput(input); |
| 1242 } | 1241 } |
| 1243 | 1242 |
| 1244 HType computeDesiredTypeForNonTargetInput(HInstruction input) { | 1243 HType computeDesiredTypeForNonTargetInput(HInstruction input) { |
| 1245 return HType.UNKNOWN; | 1244 return HType.UNKNOWN; |
| 1246 } | 1245 } |
| 1247 } | 1246 } |
| 1248 | 1247 |
| 1249 class HInvokeSuper extends HInvokeStatic { | 1248 class HInvokeSuper extends HInvokeStatic { |
| 1250 HInvokeSuper(selector, inputs) : super(selector, inputs); | 1249 HInvokeSuper(inputs) : super(inputs); |
| 1251 toString() => 'invoke super: ${element.name}'; | 1250 toString() => 'invoke super: ${element.name}'; |
| 1252 accept(HVisitor visitor) => visitor.visitInvokeSuper(this); | 1251 accept(HVisitor visitor) => visitor.visitInvokeSuper(this); |
| 1253 } | 1252 } |
| 1254 | 1253 |
| 1255 class HInvokeInterceptor extends HInvokeStatic { | 1254 class HInvokeInterceptor extends HInvokeStatic { |
| 1255 final Selector selector; |
| 1256 final SourceString name; | 1256 final SourceString name; |
| 1257 final bool getter; | 1257 final bool getter; |
| 1258 final bool setter; | 1258 final bool setter; |
| 1259 | 1259 |
| 1260 HInvokeInterceptor(Selector selector, | 1260 HInvokeInterceptor(this.selector, |
| 1261 SourceString this.name, | 1261 this.name, |
| 1262 List<HInstruction> inputs, | 1262 List<HInstruction> inputs, |
| 1263 [HType knownType = HType.UNKNOWN, | 1263 [HType knownType = HType.UNKNOWN, |
| 1264 bool this.getter = false, | 1264 this.getter = false, |
| 1265 bool this.setter = false]) | 1265 this.setter = false]) |
| 1266 : super(selector, inputs, knownType); | 1266 : super(inputs, knownType); |
| 1267 | 1267 |
| 1268 toString() => 'invoke interceptor: ${element.name}'; | 1268 toString() => 'invoke interceptor: ${element.name}'; |
| 1269 accept(HVisitor visitor) => visitor.visitInvokeInterceptor(this); | 1269 accept(HVisitor visitor) => visitor.visitInvokeInterceptor(this); |
| 1270 | 1270 |
| 1271 bool isLengthGetter() { | 1271 bool isLengthGetter() { |
| 1272 return getter && name == const SourceString('length'); | 1272 return getter && name == const SourceString('length'); |
| 1273 } | 1273 } |
| 1274 | 1274 |
| 1275 bool isLengthGetterOnStringOrArray() { | 1275 bool isLengthGetterOnStringOrArray() { |
| 1276 return isLengthGetter() && inputs[1].isIndexablePrimitive(); | 1276 return isLengthGetter() && inputs[1].isIndexablePrimitive(); |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1445 class HForeignNew extends HForeign { | 1445 class HForeignNew extends HForeign { |
| 1446 ClassElement element; | 1446 ClassElement element; |
| 1447 HForeignNew(this.element, List<HInstruction> inputs) | 1447 HForeignNew(this.element, List<HInstruction> inputs) |
| 1448 : super(const LiteralDartString("new"), | 1448 : super(const LiteralDartString("new"), |
| 1449 const LiteralDartString("Object"), inputs); | 1449 const LiteralDartString("Object"), inputs); |
| 1450 accept(HVisitor visitor) => visitor.visitForeignNew(this); | 1450 accept(HVisitor visitor) => visitor.visitForeignNew(this); |
| 1451 } | 1451 } |
| 1452 | 1452 |
| 1453 class HInvokeBinary extends HInvokeStatic { | 1453 class HInvokeBinary extends HInvokeStatic { |
| 1454 HInvokeBinary(HStatic target, HInstruction left, HInstruction right) | 1454 HInvokeBinary(HStatic target, HInstruction left, HInstruction right) |
| 1455 : super(Selector.BINARY_OPERATOR, <HInstruction>[target, left, right]); | 1455 : super(<HInstruction>[target, left, right]); |
| 1456 | 1456 |
| 1457 HInstruction get left() => inputs[1]; | 1457 HInstruction get left() => inputs[1]; |
| 1458 HInstruction get right() => inputs[2]; | 1458 HInstruction get right() => inputs[2]; |
| 1459 | 1459 |
| 1460 abstract BinaryOperation get operation(); | 1460 abstract BinaryOperation get operation(); |
| 1461 abstract get builtin(); | 1461 abstract get builtin(); |
| 1462 } | 1462 } |
| 1463 | 1463 |
| 1464 class HBinaryArithmetic extends HInvokeBinary { | 1464 class HBinaryArithmetic extends HInvokeBinary { |
| 1465 HBinaryArithmetic(HStatic target, HInstruction left, HInstruction right) | 1465 HBinaryArithmetic(HStatic target, HInstruction left, HInstruction right) |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1715 accept(HVisitor visitor) => visitor.visitBitXor(this); | 1715 accept(HVisitor visitor) => visitor.visitBitXor(this); |
| 1716 | 1716 |
| 1717 BitXorOperation get operation() => const BitXorOperation(); | 1717 BitXorOperation get operation() => const BitXorOperation(); |
| 1718 int typeCode() => 15; | 1718 int typeCode() => 15; |
| 1719 bool typeEquals(other) => other is HBitXor; | 1719 bool typeEquals(other) => other is HBitXor; |
| 1720 bool dataEquals(HInstruction other) => true; | 1720 bool dataEquals(HInstruction other) => true; |
| 1721 } | 1721 } |
| 1722 | 1722 |
| 1723 class HInvokeUnary extends HInvokeStatic { | 1723 class HInvokeUnary extends HInvokeStatic { |
| 1724 HInvokeUnary(HStatic target, HInstruction input) | 1724 HInvokeUnary(HStatic target, HInstruction input) |
| 1725 : super(Selector.UNARY_OPERATOR, <HInstruction>[target, input]); | 1725 : super(<HInstruction>[target, input]); |
| 1726 | 1726 |
| 1727 HInstruction get operand() => inputs[1]; | 1727 HInstruction get operand() => inputs[1]; |
| 1728 | 1728 |
| 1729 void prepareGvn() { | 1729 void prepareGvn() { |
| 1730 // A unary arithmetic expression can take part in global value | 1730 // A unary arithmetic expression can take part in global value |
| 1731 // numbering and does not have any side-effects if its input is a | 1731 // numbering and does not have any side-effects if its input is a |
| 1732 // number. | 1732 // number. |
| 1733 if (builtin) { | 1733 if (builtin) { |
| 1734 clearAllSideEffects(); | 1734 clearAllSideEffects(); |
| 1735 setUseGvn(); | 1735 setUseGvn(); |
| (...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2250 | 2250 |
| 2251 HType get guaranteedType() => HType.MUTABLE_ARRAY; | 2251 HType get guaranteedType() => HType.MUTABLE_ARRAY; |
| 2252 | 2252 |
| 2253 void prepareGvn() { | 2253 void prepareGvn() { |
| 2254 assert(!hasSideEffects()); | 2254 assert(!hasSideEffects()); |
| 2255 } | 2255 } |
| 2256 } | 2256 } |
| 2257 | 2257 |
| 2258 class HIndex extends HInvokeStatic { | 2258 class HIndex extends HInvokeStatic { |
| 2259 HIndex(HStatic target, HInstruction receiver, HInstruction index) | 2259 HIndex(HStatic target, HInstruction receiver, HInstruction index) |
| 2260 : super(Selector.INDEX, <HInstruction>[target, receiver, index]); | 2260 : super(<HInstruction>[target, receiver, index]); |
| 2261 toString() => 'index operator'; | 2261 toString() => 'index operator'; |
| 2262 accept(HVisitor visitor) => visitor.visitIndex(this); | 2262 accept(HVisitor visitor) => visitor.visitIndex(this); |
| 2263 | 2263 |
| 2264 void prepareGvn() { | 2264 void prepareGvn() { |
| 2265 if (builtin) { | 2265 if (builtin) { |
| 2266 clearAllSideEffects(); | 2266 clearAllSideEffects(); |
| 2267 } else { | 2267 } else { |
| 2268 setAllSideEffects(); | 2268 setAllSideEffects(); |
| 2269 } | 2269 } |
| 2270 } | 2270 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2284 } | 2284 } |
| 2285 | 2285 |
| 2286 bool get builtin() => receiver.isIndexablePrimitive() && index.isInteger(); | 2286 bool get builtin() => receiver.isIndexablePrimitive() && index.isInteger(); |
| 2287 } | 2287 } |
| 2288 | 2288 |
| 2289 class HIndexAssign extends HInvokeStatic { | 2289 class HIndexAssign extends HInvokeStatic { |
| 2290 HIndexAssign(HStatic target, | 2290 HIndexAssign(HStatic target, |
| 2291 HInstruction receiver, | 2291 HInstruction receiver, |
| 2292 HInstruction index, | 2292 HInstruction index, |
| 2293 HInstruction value) | 2293 HInstruction value) |
| 2294 : super(Selector.INDEX_SET, | 2294 : super(<HInstruction>[target, receiver, index, value]); |
| 2295 <HInstruction>[target, receiver, index, value]); | |
| 2296 toString() => 'index assign operator'; | 2295 toString() => 'index assign operator'; |
| 2297 accept(HVisitor visitor) => visitor.visitIndexAssign(this); | 2296 accept(HVisitor visitor) => visitor.visitIndexAssign(this); |
| 2298 | 2297 |
| 2299 HInstruction get receiver() => inputs[1]; | 2298 HInstruction get receiver() => inputs[1]; |
| 2300 HInstruction get index() => inputs[2]; | 2299 HInstruction get index() => inputs[2]; |
| 2301 HInstruction get value() => inputs[3]; | 2300 HInstruction get value() => inputs[3]; |
| 2302 | 2301 |
| 2303 // Note, that we don't have a computeTypeFromInputTypes, since [HIndexAssign] | 2302 // Note, that we don't have a computeTypeFromInputTypes, since [HIndexAssign] |
| 2304 // is never used as input. | 2303 // is never used as input. |
| 2305 | 2304 |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2716 HBasicBlock get start() => expression.start; | 2715 HBasicBlock get start() => expression.start; |
| 2717 HBasicBlock get end() { | 2716 HBasicBlock get end() { |
| 2718 // We don't create a switch block if there are no cases. | 2717 // We don't create a switch block if there are no cases. |
| 2719 assert(!statements.isEmpty()); | 2718 assert(!statements.isEmpty()); |
| 2720 return statements.last().end; | 2719 return statements.last().end; |
| 2721 } | 2720 } |
| 2722 | 2721 |
| 2723 bool accept(HStatementInformationVisitor visitor) => | 2722 bool accept(HStatementInformationVisitor visitor) => |
| 2724 visitor.visitSwitchInfo(this); | 2723 visitor.visitSwitchInfo(this); |
| 2725 } | 2724 } |
| OLD | NEW |