OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/compiler/access-builder.h" | 6 #include "src/compiler/access-builder.h" |
7 #include "src/compiler/js-graph.h" | 7 #include "src/compiler/js-graph.h" |
8 #include "src/compiler/js-typed-lowering.h" | 8 #include "src/compiler/js-typed-lowering.h" |
9 #include "src/compiler/linkage.h" | 9 #include "src/compiler/linkage.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 1546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1557 } | 1557 } |
1558 | 1558 |
1559 return NoChange(); | 1559 return NoChange(); |
1560 } | 1560 } |
1561 | 1561 |
1562 | 1562 |
1563 Reduction JSTypedLowering::ReduceJSCallFunction(Node* node) { | 1563 Reduction JSTypedLowering::ReduceJSCallFunction(Node* node) { |
1564 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); | 1564 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); |
1565 CallFunctionParameters const& p = CallFunctionParametersOf(node->op()); | 1565 CallFunctionParameters const& p = CallFunctionParametersOf(node->op()); |
1566 int const arity = static_cast<int>(p.arity() - 2); | 1566 int const arity = static_cast<int>(p.arity() - 2); |
1567 ConvertReceiverMode const convert_mode = p.convert_mode(); | 1567 ConvertReceiverMode convert_mode = p.convert_mode(); |
1568 Node* target = NodeProperties::GetValueInput(node, 0); | 1568 Node* target = NodeProperties::GetValueInput(node, 0); |
1569 Type* target_type = NodeProperties::GetType(target); | 1569 Type* target_type = NodeProperties::GetType(target); |
1570 Node* receiver = NodeProperties::GetValueInput(node, 1); | 1570 Node* receiver = NodeProperties::GetValueInput(node, 1); |
1571 Type* receiver_type = NodeProperties::GetType(receiver); | 1571 Type* receiver_type = NodeProperties::GetType(receiver); |
1572 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 1572 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); |
1573 Node* effect = NodeProperties::GetEffectInput(node); | 1573 Node* effect = NodeProperties::GetEffectInput(node); |
1574 Node* control = NodeProperties::GetControlInput(node); | 1574 Node* control = NodeProperties::GetControlInput(node); |
1575 | 1575 |
| 1576 // Try to infer receiver {convert_mode} from {receiver} type. |
| 1577 if (receiver_type->Is(Type::NullOrUndefined())) { |
| 1578 convert_mode = ConvertReceiverMode::kNullOrUndefined; |
| 1579 } else if (!receiver_type->Maybe(Type::NullOrUndefined())) { |
| 1580 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; |
| 1581 } |
| 1582 |
1576 // Check if {target} is a known JSFunction. | 1583 // Check if {target} is a known JSFunction. |
1577 if (target_type->IsConstant() && | 1584 if (target_type->IsConstant() && |
1578 target_type->AsConstant()->Value()->IsJSFunction()) { | 1585 target_type->AsConstant()->Value()->IsJSFunction()) { |
1579 Handle<JSFunction> function = | 1586 Handle<JSFunction> function = |
1580 Handle<JSFunction>::cast(target_type->AsConstant()->Value()); | 1587 Handle<JSFunction>::cast(target_type->AsConstant()->Value()); |
1581 Handle<SharedFunctionInfo> shared(function->shared(), isolate()); | 1588 Handle<SharedFunctionInfo> shared(function->shared(), isolate()); |
1582 | 1589 |
1583 // Class constructors are callable, but [[Call]] will raise an exception. | 1590 // Class constructors are callable, but [[Call]] will raise an exception. |
1584 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList ). | 1591 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList ). |
1585 if (IsClassConstructor(shared->kind())) return NoChange(); | 1592 if (IsClassConstructor(shared->kind())) return NoChange(); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1638 // Remove the eager bailout frame state. | 1645 // Remove the eager bailout frame state. |
1639 NodeProperties::RemoveFrameStateInput(node, 1); | 1646 NodeProperties::RemoveFrameStateInput(node, 1); |
1640 | 1647 |
1641 // Compute flags for the call. | 1648 // Compute flags for the call. |
1642 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; | 1649 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; |
1643 if (p.tail_call_mode() == TailCallMode::kAllow) { | 1650 if (p.tail_call_mode() == TailCallMode::kAllow) { |
1644 flags |= CallDescriptor::kSupportsTailCalls; | 1651 flags |= CallDescriptor::kSupportsTailCalls; |
1645 } | 1652 } |
1646 | 1653 |
1647 // Patch {node} to an indirect call via the CallFunction builtin. | 1654 // Patch {node} to an indirect call via the CallFunction builtin. |
1648 Callable callable = CodeFactory::CallFunction(isolate()); | 1655 Callable callable = CodeFactory::CallFunction(isolate(), convert_mode); |
1649 node->InsertInput(graph()->zone(), 0, | 1656 node->InsertInput(graph()->zone(), 0, |
1650 jsgraph()->HeapConstant(callable.code())); | 1657 jsgraph()->HeapConstant(callable.code())); |
1651 node->InsertInput(graph()->zone(), 2, jsgraph()->Int32Constant(arity)); | 1658 node->InsertInput(graph()->zone(), 2, jsgraph()->Int32Constant(arity)); |
1652 NodeProperties::ChangeOp( | 1659 NodeProperties::ChangeOp( |
1653 node, common()->Call(Linkage::GetStubCallDescriptor( | 1660 node, common()->Call(Linkage::GetStubCallDescriptor( |
1654 isolate(), graph()->zone(), callable.descriptor(), 1 + arity, | 1661 isolate(), graph()->zone(), callable.descriptor(), 1 + arity, |
1655 flags))); | 1662 flags))); |
1656 return Changed(node); | 1663 return Changed(node); |
1657 } | 1664 } |
1658 | 1665 |
| 1666 // Maybe we did at least learn something about the {receiver}. |
| 1667 if (p.convert_mode() != convert_mode) { |
| 1668 NodeProperties::ChangeOp( |
| 1669 node, |
| 1670 javascript()->CallFunction(p.arity(), p.language_mode(), p.feedback(), |
| 1671 convert_mode, p.tail_call_mode())); |
| 1672 return Changed(node); |
| 1673 } |
| 1674 |
1659 return NoChange(); | 1675 return NoChange(); |
1660 } | 1676 } |
1661 | 1677 |
1662 | 1678 |
1663 Reduction JSTypedLowering::ReduceJSForInDone(Node* node) { | 1679 Reduction JSTypedLowering::ReduceJSForInDone(Node* node) { |
1664 DCHECK_EQ(IrOpcode::kJSForInDone, node->opcode()); | 1680 DCHECK_EQ(IrOpcode::kJSForInDone, node->opcode()); |
1665 node->TrimInputCount(2); | 1681 node->TrimInputCount(2); |
1666 NodeProperties::ChangeOp(node, machine()->Word32Equal()); | 1682 NodeProperties::ChangeOp(node, machine()->Word32Equal()); |
1667 return Changed(node); | 1683 return Changed(node); |
1668 } | 1684 } |
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2155 } | 2171 } |
2156 | 2172 |
2157 | 2173 |
2158 MachineOperatorBuilder* JSTypedLowering::machine() const { | 2174 MachineOperatorBuilder* JSTypedLowering::machine() const { |
2159 return jsgraph()->machine(); | 2175 return jsgraph()->machine(); |
2160 } | 2176 } |
2161 | 2177 |
2162 } // namespace compiler | 2178 } // namespace compiler |
2163 } // namespace internal | 2179 } // namespace internal |
2164 } // namespace v8 | 2180 } // namespace v8 |
OLD | NEW |