OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/interpreter/bytecode-generator.h" | 5 #include "src/interpreter/bytecode-generator.h" |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
9 #include "src/interpreter/control-flow-builders.h" | 9 #include "src/interpreter/control-flow-builders.h" |
10 #include "src/objects.h" | 10 #include "src/objects.h" |
(...skipping 1588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1599 return first_arg; | 1599 return first_arg; |
1600 } | 1600 } |
1601 | 1601 |
1602 | 1602 |
1603 void BytecodeGenerator::VisitCall(Call* expr) { | 1603 void BytecodeGenerator::VisitCall(Call* expr) { |
1604 Expression* callee_expr = expr->expression(); | 1604 Expression* callee_expr = expr->expression(); |
1605 Call::CallType call_type = expr->GetCallType(isolate()); | 1605 Call::CallType call_type = expr->GetCallType(isolate()); |
1606 | 1606 |
1607 // Prepare the callee and the receiver to the function call. This depends on | 1607 // Prepare the callee and the receiver to the function call. This depends on |
1608 // the semantics of the underlying call type. | 1608 // the semantics of the underlying call type. |
1609 Register callee = execution_result()->NewRegister(); | |
1610 | 1609 |
1611 // The receiver and arguments need to be allocated consecutively for | 1610 // The receiver and arguments need to be allocated consecutively for |
1612 // Call(). Future optimizations could avoid this there are no | 1611 // Call(). We allocate the callee and receiver consecutively for calls to |
| 1612 // kLoadLookupSlot. Future optimizations could avoid this there are no |
1613 // arguments or the receiver and arguments are already consecutive. | 1613 // arguments or the receiver and arguments are already consecutive. |
1614 ZoneList<Expression*>* args = expr->arguments(); | 1614 ZoneList<Expression*>* args = expr->arguments(); |
1615 execution_result()->PrepareForConsecutiveAllocations(args->length() + 1); | 1615 execution_result()->PrepareForConsecutiveAllocations(args->length() + 2); |
| 1616 Register callee = execution_result()->NextConsecutiveRegister(); |
1616 Register receiver = execution_result()->NextConsecutiveRegister(); | 1617 Register receiver = execution_result()->NextConsecutiveRegister(); |
1617 | 1618 |
1618 bool possibly_eval = false; | |
1619 switch (call_type) { | 1619 switch (call_type) { |
1620 case Call::NAMED_PROPERTY_CALL: | 1620 case Call::NAMED_PROPERTY_CALL: |
1621 case Call::KEYED_PROPERTY_CALL: { | 1621 case Call::KEYED_PROPERTY_CALL: { |
1622 Property* property = callee_expr->AsProperty(); | 1622 Property* property = callee_expr->AsProperty(); |
1623 VisitForAccumulatorValue(property->obj()); | 1623 VisitForAccumulatorValue(property->obj()); |
1624 builder()->StoreAccumulatorInRegister(receiver); | 1624 builder()->StoreAccumulatorInRegister(receiver); |
1625 VisitPropertyLoadForAccumulator(receiver, property); | 1625 VisitPropertyLoadForAccumulator(receiver, property); |
1626 builder()->StoreAccumulatorInRegister(callee); | 1626 builder()->StoreAccumulatorInRegister(callee); |
1627 break; | 1627 break; |
1628 } | 1628 } |
1629 case Call::GLOBAL_CALL: { | 1629 case Call::GLOBAL_CALL: { |
1630 // Receiver is undefined for global calls. | 1630 // Receiver is undefined for global calls. |
1631 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); | 1631 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); |
1632 // Load callee as a global variable. | 1632 // Load callee as a global variable. |
1633 VariableProxy* proxy = callee_expr->AsVariableProxy(); | 1633 VariableProxy* proxy = callee_expr->AsVariableProxy(); |
1634 VisitVariableLoadForAccumulatorValue(proxy->var(), | 1634 VisitVariableLoadForAccumulatorValue(proxy->var(), |
1635 proxy->VariableFeedbackSlot()); | 1635 proxy->VariableFeedbackSlot()); |
1636 builder()->StoreAccumulatorInRegister(callee); | 1636 builder()->StoreAccumulatorInRegister(callee); |
1637 break; | 1637 break; |
1638 } | 1638 } |
| 1639 case Call::LOOKUP_SLOT_CALL: |
1639 case Call::POSSIBLY_EVAL_CALL: { | 1640 case Call::POSSIBLY_EVAL_CALL: { |
1640 possibly_eval = true; | |
1641 if (callee_expr->AsVariableProxy()->var()->IsLookupSlot()) { | 1641 if (callee_expr->AsVariableProxy()->var()->IsLookupSlot()) { |
1642 TemporaryRegisterScope temporary_register_scope(builder()); | 1642 TemporaryRegisterScope temporary_register_scope(builder()); |
1643 temporary_register_scope.PrepareForConsecutiveAllocations(2); | 1643 temporary_register_scope.PrepareForConsecutiveAllocations(2); |
1644 Register context = temporary_register_scope.NextConsecutiveRegister(); | 1644 Register context = temporary_register_scope.NextConsecutiveRegister(); |
1645 Register name = temporary_register_scope.NextConsecutiveRegister(); | 1645 Register name = temporary_register_scope.NextConsecutiveRegister(); |
1646 | 1646 |
| 1647 // Call LoadLookupSlot to get the callee and receiver. |
| 1648 DCHECK(Register::AreContiguous(callee, receiver)); |
1647 Variable* variable = callee_expr->AsVariableProxy()->var(); | 1649 Variable* variable = callee_expr->AsVariableProxy()->var(); |
1648 builder() | 1650 builder() |
1649 ->MoveRegister(Register::function_context(), context) | 1651 ->MoveRegister(Register::function_context(), context) |
1650 .LoadLiteral(variable->name()) | 1652 .LoadLiteral(variable->name()) |
1651 .StoreAccumulatorInRegister(name); | 1653 .StoreAccumulatorInRegister(name) |
1652 | 1654 .CallRuntimeForPair(Runtime::kLoadLookupSlot, context, 2, callee); |
1653 // Call LoadLookupSlot to get the callee and receiver. Reuse the context | |
1654 // and name arguments as the return registers (since these are | |
1655 // consecutive), and them move into callee and receiver registers. | |
1656 builder() | |
1657 ->CallRuntimeForPair(Runtime::kLoadLookupSlot, context, 2, context) | |
1658 .MoveRegister(context, callee) | |
1659 .MoveRegister(name, receiver); | |
1660 break; | 1655 break; |
1661 } | 1656 } |
1662 // Fall through. | 1657 // Fall through. |
| 1658 DCHECK_EQ(call_type, Call::POSSIBLY_EVAL_CALL); |
1663 } | 1659 } |
1664 case Call::OTHER_CALL: { | 1660 case Call::OTHER_CALL: { |
1665 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); | 1661 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); |
1666 VisitForAccumulatorValue(callee_expr); | 1662 VisitForAccumulatorValue(callee_expr); |
1667 builder()->StoreAccumulatorInRegister(callee); | 1663 builder()->StoreAccumulatorInRegister(callee); |
1668 break; | 1664 break; |
1669 } | 1665 } |
1670 case Call::NAMED_SUPER_PROPERTY_CALL: | 1666 case Call::NAMED_SUPER_PROPERTY_CALL: |
1671 case Call::KEYED_SUPER_PROPERTY_CALL: | 1667 case Call::KEYED_SUPER_PROPERTY_CALL: |
1672 case Call::LOOKUP_SLOT_CALL: | |
1673 case Call::SUPER_CALL: | 1668 case Call::SUPER_CALL: |
1674 UNIMPLEMENTED(); | 1669 UNIMPLEMENTED(); |
1675 } | 1670 } |
1676 | 1671 |
1677 // Evaluate all arguments to the function call and store in sequential | 1672 // Evaluate all arguments to the function call and store in sequential |
1678 // registers. | 1673 // registers. |
1679 Register arg = VisitArguments(args); | 1674 Register arg = VisitArguments(args); |
1680 CHECK(args->length() == 0 || arg.index() == receiver.index() + 1); | 1675 CHECK(args->length() == 0 || arg.index() == receiver.index() + 1); |
1681 | 1676 |
1682 // Resolve callee for a potential direct eval call. This block will mutate the | 1677 // Resolve callee for a potential direct eval call. This block will mutate the |
1683 // callee value. | 1678 // callee value. |
1684 if (possibly_eval && args->length() > 0) { | 1679 if (call_type == Call::POSSIBLY_EVAL_CALL && args->length() > 0) { |
1685 TemporaryRegisterScope temporary_register_scope(builder()); | 1680 TemporaryRegisterScope temporary_register_scope(builder()); |
1686 temporary_register_scope.PrepareForConsecutiveAllocations(5); | 1681 temporary_register_scope.PrepareForConsecutiveAllocations(5); |
1687 Register callee_for_eval = | 1682 Register callee_for_eval = |
1688 temporary_register_scope.NextConsecutiveRegister(); | 1683 temporary_register_scope.NextConsecutiveRegister(); |
1689 Register source = temporary_register_scope.NextConsecutiveRegister(); | 1684 Register source = temporary_register_scope.NextConsecutiveRegister(); |
1690 Register function = temporary_register_scope.NextConsecutiveRegister(); | 1685 Register function = temporary_register_scope.NextConsecutiveRegister(); |
1691 Register language = temporary_register_scope.NextConsecutiveRegister(); | 1686 Register language = temporary_register_scope.NextConsecutiveRegister(); |
1692 Register position = temporary_register_scope.NextConsecutiveRegister(); | 1687 Register position = temporary_register_scope.NextConsecutiveRegister(); |
1693 | 1688 |
1694 // Set up arguments for ResolvePossiblyDirectEval by copying callee, source | 1689 // Set up arguments for ResolvePossiblyDirectEval by copying callee, source |
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2285 } | 2280 } |
2286 | 2281 |
2287 | 2282 |
2288 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 2283 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
2289 return info()->feedback_vector()->GetIndex(slot); | 2284 return info()->feedback_vector()->GetIndex(slot); |
2290 } | 2285 } |
2291 | 2286 |
2292 } // namespace interpreter | 2287 } // namespace interpreter |
2293 } // namespace internal | 2288 } // namespace internal |
2294 } // namespace v8 | 2289 } // namespace v8 |
OLD | NEW |