| 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 class SsaCodeGeneratorTask extends CompilerTask { | 7 class SsaCodeGeneratorTask extends CompilerTask { |
| 8 | 8 |
| 9 final JavaScriptBackend backend; | 9 final JavaScriptBackend backend; |
| 10 | 10 |
| (...skipping 1552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1563 } | 1563 } |
| 1564 backend.registerUseInterceptor(world); | 1564 backend.registerUseInterceptor(world); |
| 1565 } | 1565 } |
| 1566 | 1566 |
| 1567 Selector getOptimizedSelectorFor(HInvokeDynamic node, Selector selector) { | 1567 Selector getOptimizedSelectorFor(HInvokeDynamic node, Selector selector) { |
| 1568 if (node.element != null) { | 1568 if (node.element != null) { |
| 1569 // Create an artificial type mask to make sure only | 1569 // Create an artificial type mask to make sure only |
| 1570 // [node.element] will be enqueued. We're not using the receiver | 1570 // [node.element] will be enqueued. We're not using the receiver |
| 1571 // type because our optimizations might end up in a state where the | 1571 // type because our optimizations might end up in a state where the |
| 1572 // invoke dynamic knows more than the receiver. | 1572 // invoke dynamic knows more than the receiver. |
| 1573 ClassElement enclosing = node.element.getEnclosingClass(); |
| 1573 HType receiverType = new HType.fromMask( | 1574 HType receiverType = new HType.fromMask( |
| 1574 new TypeMask.nonNullExact(node.element.getEnclosingClass().rawType), | 1575 new TypeMask.nonNullExact(enclosing.declaration), |
| 1575 compiler); | 1576 compiler); |
| 1576 return receiverType.refine(selector, compiler); | 1577 return receiverType.refine(selector, compiler); |
| 1577 } | 1578 } |
| 1578 // If [JSInvocationMirror._invokeOn] has been called, we must not create a | 1579 // If [JSInvocationMirror._invokeOn] has been called, we must not create a |
| 1579 // typed selector based on the receiver type. | 1580 // typed selector based on the receiver type. |
| 1580 if (backend.compiler.enabledInvokeOn) { | 1581 if (backend.compiler.enabledInvokeOn) { |
| 1581 return selector.asUntyped; | 1582 return selector.asUntyped; |
| 1582 } | 1583 } |
| 1583 HType receiverType = node.getDartReceiver(compiler).instructionType; | 1584 HType receiverType = node.getDartReceiver(compiler).instructionType; |
| 1584 return receiverType.refine(selector, compiler); | 1585 return receiverType.refine(selector, compiler); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1672 } else { | 1673 } else { |
| 1673 push(access, node); | 1674 push(access, node); |
| 1674 } | 1675 } |
| 1675 } else { | 1676 } else { |
| 1676 Selector selector = node.selector; | 1677 Selector selector = node.selector; |
| 1677 String methodName; | 1678 String methodName; |
| 1678 if (selector.isGetter()) { | 1679 if (selector.isGetter()) { |
| 1679 // If the selector we need to register a typed getter to the | 1680 // If the selector we need to register a typed getter to the |
| 1680 // [world]. The emitter needs to know if it needs to emit a | 1681 // [world]. The emitter needs to know if it needs to emit a |
| 1681 // bound closure for a method. | 1682 // bound closure for a method. |
| 1682 TypeMask receiverType = new TypeMask.nonNullExact(superClass.rawType); | 1683 TypeMask receiverType = new TypeMask.nonNullExact(superClass); |
| 1683 selector = new TypedSelector(receiverType, selector); | 1684 selector = new TypedSelector(receiverType, selector); |
| 1684 world.registerDynamicGetter(selector); | 1685 world.registerDynamicGetter(selector); |
| 1685 methodName = backend.namer.invocationName(selector); | 1686 methodName = backend.namer.invocationName(selector); |
| 1686 } else { | 1687 } else { |
| 1687 methodName = backend.namer.getNameOfInstanceMember(superMethod); | 1688 methodName = backend.namer.getNameOfInstanceMember(superMethod); |
| 1688 } | 1689 } |
| 1689 js.PropertyAccess method = | 1690 js.PropertyAccess method = |
| 1690 backend.namer.elementAccess(superClass)['prototype'][methodName]; | 1691 backend.namer.elementAccess(superClass)['prototype'][methodName]; |
| 1691 push(jsPropertyCall( | 1692 push(jsPropertyCall( |
| 1692 method, "call", visitArguments(node.inputs, start: 0)), node); | 1693 method, "call", visitArguments(node.inputs, start: 0)), node); |
| (...skipping 762 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2455 attachLocationToLast(node); | 2456 attachLocationToLast(node); |
| 2456 } | 2457 } |
| 2457 } | 2458 } |
| 2458 } | 2459 } |
| 2459 | 2460 |
| 2460 js.Expression generateTest(HCheck node) { | 2461 js.Expression generateTest(HCheck node) { |
| 2461 HInstruction input = node.checkedInput; | 2462 HInstruction input = node.checkedInput; |
| 2462 TypeMask receiver = input.instructionType.computeMask(compiler); | 2463 TypeMask receiver = input.instructionType.computeMask(compiler); |
| 2463 TypeMask mask = node.instructionType.computeMask(compiler); | 2464 TypeMask mask = node.instructionType.computeMask(compiler); |
| 2464 // Figure out if it is beneficial to turn this into a null check. | 2465 // Figure out if it is beneficial to turn this into a null check. |
| 2465 // V8 generally prefers 'typeof' checks, but for integers and | 2466 // V8 generally prefers 'typeof' checks, but for integers and |
| 2466 // indexable primitives we cannot compile this test into a single | 2467 // indexable primitives we cannot compile this test into a single |
| 2467 // typeof check so the null check is cheaper. | 2468 // typeof check so the null check is cheaper. |
| 2468 bool turnIntoNullCheck = (mask.nullable() == receiver) | 2469 bool turnIntoNullCheck = (mask.nullable() == receiver) |
| 2469 && (node.isInteger() || node.isIndexablePrimitive(compiler)); | 2470 && (node.isInteger() || node.isIndexablePrimitive(compiler)); |
| 2470 js.Expression test; | 2471 js.Expression test; |
| 2471 if (turnIntoNullCheck) { | 2472 if (turnIntoNullCheck) { |
| 2472 use(input); | 2473 use(input); |
| 2473 test = new js.Binary("==", pop(), new js.LiteralNull()); | 2474 test = new js.Binary("==", pop(), new js.LiteralNull()); |
| 2474 } else if (node.isInteger()) { | 2475 } else if (node.isInteger()) { |
| 2475 // input is !int | 2476 // input is !int |
| (...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3038 if (leftType.canBeNull() && rightType.canBeNull()) { | 3039 if (leftType.canBeNull() && rightType.canBeNull()) { |
| 3039 if (left.isConstantNull() || right.isConstantNull() || | 3040 if (left.isConstantNull() || right.isConstantNull() || |
| 3040 (leftType.isPrimitive(compiler) && leftType == rightType)) { | 3041 (leftType.isPrimitive(compiler) && leftType == rightType)) { |
| 3041 return '=='; | 3042 return '=='; |
| 3042 } | 3043 } |
| 3043 return null; | 3044 return null; |
| 3044 } else { | 3045 } else { |
| 3045 return '==='; | 3046 return '==='; |
| 3046 } | 3047 } |
| 3047 } | 3048 } |
| OLD | NEW |