| 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 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 abstract class HVisitor<R> { | 7 abstract class HVisitor<R> { |
| 8 R visitAdd(HAdd node); | 8 R visitAdd(HAdd node); |
| 9 R visitBailoutTarget(HBailoutTarget node); | 9 R visitBailoutTarget(HBailoutTarget node); |
| 10 R visitBitAnd(HBitAnd node); | 10 R visitBitAnd(HBitAnd node); |
| (...skipping 1230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1241 * The first argument must be the target: either an [HStatic] node, or | 1241 * The first argument must be the target: either an [HStatic] node, or |
| 1242 * the receiver of a method-call. The remaining inputs are the arguments | 1242 * the receiver of a method-call. The remaining inputs are the arguments |
| 1243 * to the invocation. | 1243 * to the invocation. |
| 1244 */ | 1244 */ |
| 1245 HInvoke(List<HInstruction> inputs) : super(inputs) { | 1245 HInvoke(List<HInstruction> inputs) : super(inputs) { |
| 1246 sideEffects.setAllSideEffects(); | 1246 sideEffects.setAllSideEffects(); |
| 1247 sideEffects.setDependsOnSomething(); | 1247 sideEffects.setDependsOnSomething(); |
| 1248 } | 1248 } |
| 1249 static const int ARGUMENTS_OFFSET = 1; | 1249 static const int ARGUMENTS_OFFSET = 1; |
| 1250 bool canThrow() => true; | 1250 bool canThrow() => true; |
| 1251 |
| 1252 /** |
| 1253 * Returns whether this call is on an intercepted method. |
| 1254 */ |
| 1255 bool get isInterceptedCall { |
| 1256 // We know it's a selector call if it follows the interceptor |
| 1257 // calling convention, which adds the actual receiver as a |
| 1258 // parameter to the call. |
| 1259 return inputs.length - 2 == selector.argumentCount; |
| 1260 } |
| 1251 } | 1261 } |
| 1252 | 1262 |
| 1253 abstract class HInvokeDynamic extends HInvoke { | 1263 abstract class HInvokeDynamic extends HInvoke { |
| 1254 final InvokeDynamicSpecializer specializer; | 1264 final InvokeDynamicSpecializer specializer; |
| 1255 final Selector selector; | 1265 final Selector selector; |
| 1256 Element element; | 1266 Element element; |
| 1257 | 1267 |
| 1258 HInvokeDynamic(Selector selector, | 1268 HInvokeDynamic(Selector selector, |
| 1259 this.element, | 1269 this.element, |
| 1260 List<HInstruction> inputs, | 1270 List<HInstruction> inputs, |
| 1261 [bool isIntercepted = false]) | 1271 [bool isIntercepted = false]) |
| 1262 : super(inputs), | 1272 : super(inputs), |
| 1263 this.selector = selector, | 1273 this.selector = selector, |
| 1264 specializer = isIntercepted | 1274 specializer = isIntercepted |
| 1265 ? InvokeDynamicSpecializer.lookupSpecializer(selector) | 1275 ? InvokeDynamicSpecializer.lookupSpecializer(selector) |
| 1266 : const InvokeDynamicSpecializer(); | 1276 : const InvokeDynamicSpecializer(); |
| 1267 toString() => 'invoke dynamic: $selector'; | 1277 toString() => 'invoke dynamic: $selector'; |
| 1268 HInstruction get receiver => inputs[0]; | 1278 HInstruction get receiver => inputs[0]; |
| 1269 HInstruction getDartReceiver(Compiler compiler) { | 1279 HInstruction getDartReceiver(Compiler compiler) { |
| 1270 return isCallOnInterceptor(compiler) ? inputs[1] : inputs[0]; | 1280 return isCallOnInterceptor(compiler) ? inputs[1] : inputs[0]; |
| 1271 } | 1281 } |
| 1272 | 1282 |
| 1273 /** | 1283 /** |
| 1274 * Returns whether this call is on an intercepted method. | |
| 1275 */ | |
| 1276 bool get isInterceptedCall { | |
| 1277 // We know it's a selector call if it follows the interceptor | |
| 1278 // calling convention, which adds the actual receiver as a | |
| 1279 // parameter to the call. | |
| 1280 return inputs.length - 2 == selector.argumentCount; | |
| 1281 } | |
| 1282 | |
| 1283 /** | |
| 1284 * Returns whether this call is on an interceptor object. | 1284 * Returns whether this call is on an interceptor object. |
| 1285 */ | 1285 */ |
| 1286 bool isCallOnInterceptor(Compiler compiler) { | 1286 bool isCallOnInterceptor(Compiler compiler) { |
| 1287 return isInterceptedCall && receiver.isInterceptor(compiler); | 1287 return isInterceptedCall && receiver.isInterceptor(compiler); |
| 1288 } | 1288 } |
| 1289 | 1289 |
| 1290 int typeCode() => HInstruction.INVOKE_DYNAMIC_TYPECODE; | 1290 int typeCode() => HInstruction.INVOKE_DYNAMIC_TYPECODE; |
| 1291 bool typeEquals(other) => other is HInvokeDynamic; | 1291 bool typeEquals(other) => other is HInvokeDynamic; |
| 1292 bool dataEquals(HInvokeDynamic other) { | 1292 bool dataEquals(HInvokeDynamic other) { |
| 1293 return selector == other.selector && element == other.element; | 1293 return selector == other.selector && element == other.element; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1368 | 1368 |
| 1369 toString() => 'invoke static: ${element.name}'; | 1369 toString() => 'invoke static: ${element.name}'; |
| 1370 accept(HVisitor visitor) => visitor.visitInvokeStatic(this); | 1370 accept(HVisitor visitor) => visitor.visitInvokeStatic(this); |
| 1371 int typeCode() => HInstruction.INVOKE_STATIC_TYPECODE; | 1371 int typeCode() => HInstruction.INVOKE_STATIC_TYPECODE; |
| 1372 } | 1372 } |
| 1373 | 1373 |
| 1374 class HInvokeSuper extends HInvokeStatic { | 1374 class HInvokeSuper extends HInvokeStatic { |
| 1375 /** The class where the call to super is being done. */ | 1375 /** The class where the call to super is being done. */ |
| 1376 final ClassElement caller; | 1376 final ClassElement caller; |
| 1377 final bool isSetter; | 1377 final bool isSetter; |
| 1378 final Selector selector; |
| 1378 | 1379 |
| 1379 HInvokeSuper(Element element, this.caller, inputs, {this.isSetter}) | 1380 HInvokeSuper(Element element, |
| 1381 this.caller, |
| 1382 this.selector, |
| 1383 inputs, |
| 1384 {this.isSetter}) |
| 1380 : super(element, inputs, HType.UNKNOWN); | 1385 : super(element, inputs, HType.UNKNOWN); |
| 1381 toString() => 'invoke super: ${element.name}'; | 1386 toString() => 'invoke super: ${element.name}'; |
| 1382 accept(HVisitor visitor) => visitor.visitInvokeSuper(this); | 1387 accept(HVisitor visitor) => visitor.visitInvokeSuper(this); |
| 1383 | 1388 |
| 1384 HInstruction get value { | 1389 HInstruction get value { |
| 1385 assert(isSetter); | 1390 assert(isSetter); |
| 1386 // Index 0: 'this'. | 1391 // Index 0: 'this'. |
| 1387 return inputs[1]; | 1392 return inputs[1]; |
| 1388 } | 1393 } |
| 1389 } | 1394 } |
| (...skipping 1214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2604 HBasicBlock get start => expression.start; | 2609 HBasicBlock get start => expression.start; |
| 2605 HBasicBlock get end { | 2610 HBasicBlock get end { |
| 2606 // We don't create a switch block if there are no cases. | 2611 // We don't create a switch block if there are no cases. |
| 2607 assert(!statements.isEmpty); | 2612 assert(!statements.isEmpty); |
| 2608 return statements.last.end; | 2613 return statements.last.end; |
| 2609 } | 2614 } |
| 2610 | 2615 |
| 2611 bool accept(HStatementInformationVisitor visitor) => | 2616 bool accept(HStatementInformationVisitor visitor) => |
| 2612 visitor.visitSwitchInfo(this); | 2617 visitor.visitSwitchInfo(this); |
| 2613 } | 2618 } |
| OLD | NEW |