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 #if V8_TARGET_ARCH_PPC | 5 #if V8_TARGET_ARCH_PPC |
6 | 6 |
7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 1566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1577 __ LoadP(r4, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + | 1577 __ LoadP(r4, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + |
1578 kPointerSize))); | 1578 kPointerSize))); |
1579 int stack_adjustment = kPointerSize; // adjust for receiver | 1579 int stack_adjustment = kPointerSize; // adjust for receiver |
1580 __ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR, stack_adjustment); | 1580 __ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR, stack_adjustment); |
1581 __ SmiToPtrArrayOffset(r0, r4); | 1581 __ SmiToPtrArrayOffset(r0, r4); |
1582 __ add(sp, sp, r0); | 1582 __ add(sp, sp, r0); |
1583 } | 1583 } |
1584 | 1584 |
1585 | 1585 |
1586 // static | 1586 // static |
1587 void Builtins::Generate_CallFunction(MacroAssembler* masm) { | 1587 void Builtins::Generate_CallFunction(MacroAssembler* masm, |
| 1588 ConvertReceiverMode mode) { |
1588 // ----------- S t a t e ------------- | 1589 // ----------- S t a t e ------------- |
1589 // -- r3 : the number of arguments (not including the receiver) | 1590 // -- r3 : the number of arguments (not including the receiver) |
1590 // -- r4 : the function to call (checked to be a JSFunction) | 1591 // -- r4 : the function to call (checked to be a JSFunction) |
1591 // ----------------------------------- | 1592 // ----------------------------------- |
| 1593 __ AssertFunction(r4); |
| 1594 |
1592 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) | 1595 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) |
1593 | 1596 // Check that the function is not a "classConstructor". |
1594 Label convert, convert_global_proxy, convert_to_object, done_convert; | 1597 Label class_constructor; |
1595 __ AssertFunction(r4); | |
1596 __ LoadP(r5, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); | 1598 __ LoadP(r5, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); |
1597 __ lwz(r6, FieldMemOperand(r5, SharedFunctionInfo::kCompilerHintsOffset)); | 1599 __ lwz(r6, FieldMemOperand(r5, SharedFunctionInfo::kCompilerHintsOffset)); |
1598 { | 1600 __ TestBitMask(r6, SharedFunctionInfo::kClassConstructorBits, r0); |
1599 Label non_class_constructor; | 1601 __ bne(&class_constructor, cr0); |
1600 // Check whether the current function is a classConstructor. | |
1601 __ TestBitMask(r6, SharedFunctionInfo::kClassConstructorBits, r0); | |
1602 __ beq(&non_class_constructor, cr0); | |
1603 // Step: 2, If we call a classConstructor Function throw a TypeError. | |
1604 { | |
1605 FrameAndConstantPoolScope frame(masm, StackFrame::INTERNAL); | |
1606 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0); | |
1607 } | |
1608 __ bind(&non_class_constructor); | |
1609 } | |
1610 | 1602 |
1611 // Enter the context of the function; ToObject has to run in the function | 1603 // Enter the context of the function; ToObject has to run in the function |
1612 // context, and we also need to take the global proxy from the function | 1604 // context, and we also need to take the global proxy from the function |
1613 // context in case of conversion. | 1605 // context in case of conversion. |
1614 __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset)); | 1606 __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset)); |
1615 // We need to convert the receiver for non-native sloppy mode functions. | 1607 // We need to convert the receiver for non-native sloppy mode functions. |
| 1608 Label done_convert; |
1616 __ andi(r0, r6, Operand((1 << SharedFunctionInfo::kStrictModeBit) | | 1609 __ andi(r0, r6, Operand((1 << SharedFunctionInfo::kStrictModeBit) | |
1617 (1 << SharedFunctionInfo::kNativeBit))); | 1610 (1 << SharedFunctionInfo::kNativeBit))); |
1618 __ bne(&done_convert, cr0); | 1611 __ bne(&done_convert, cr0); |
1619 { | 1612 { |
1620 __ ShiftLeftImm(r6, r3, Operand(kPointerSizeLog2)); | |
1621 __ LoadPX(r6, MemOperand(sp, r6)); | |
1622 | |
1623 // ----------- S t a t e ------------- | 1613 // ----------- S t a t e ------------- |
1624 // -- r3 : the number of arguments (not including the receiver) | 1614 // -- r3 : the number of arguments (not including the receiver) |
1625 // -- r4 : the function to call (checked to be a JSFunction) | 1615 // -- r4 : the function to call (checked to be a JSFunction) |
1626 // -- r5 : the shared function info. | 1616 // -- r5 : the shared function info. |
1627 // -- r6 : the receiver | |
1628 // -- cp : the function context. | 1617 // -- cp : the function context. |
1629 // ----------------------------------- | 1618 // ----------------------------------- |
1630 | 1619 |
1631 Label convert_receiver; | 1620 if (mode == ConvertReceiverMode::kNullOrUndefined) { |
1632 __ JumpIfSmi(r6, &convert_to_object); | |
1633 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); | |
1634 __ CompareObjectType(r6, r7, r7, FIRST_JS_RECEIVER_TYPE); | |
1635 __ bge(&done_convert); | |
1636 __ JumpIfRoot(r6, Heap::kUndefinedValueRootIndex, &convert_global_proxy); | |
1637 __ JumpIfNotRoot(r6, Heap::kNullValueRootIndex, &convert_to_object); | |
1638 __ bind(&convert_global_proxy); | |
1639 { | |
1640 // Patch receiver to global proxy. | 1621 // Patch receiver to global proxy. |
1641 __ LoadGlobalProxy(r6); | 1622 __ LoadGlobalProxy(r6); |
| 1623 } else { |
| 1624 Label convert_to_object, convert_receiver; |
| 1625 __ ShiftLeftImm(r6, r3, Operand(kPointerSizeLog2)); |
| 1626 __ LoadPX(r6, MemOperand(sp, r6)); |
| 1627 __ JumpIfSmi(r6, &convert_to_object); |
| 1628 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
| 1629 __ CompareObjectType(r6, r7, r7, FIRST_JS_RECEIVER_TYPE); |
| 1630 __ bge(&done_convert); |
| 1631 if (mode != ConvertReceiverMode::kNotNullOrUndefined) { |
| 1632 Label convert_global_proxy; |
| 1633 __ JumpIfRoot(r6, Heap::kUndefinedValueRootIndex, |
| 1634 &convert_global_proxy); |
| 1635 __ JumpIfNotRoot(r6, Heap::kNullValueRootIndex, &convert_to_object); |
| 1636 __ bind(&convert_global_proxy); |
| 1637 { |
| 1638 // Patch receiver to global proxy. |
| 1639 __ LoadGlobalProxy(r6); |
| 1640 } |
| 1641 __ b(&convert_receiver); |
| 1642 } |
| 1643 __ bind(&convert_to_object); |
| 1644 { |
| 1645 // Convert receiver using ToObject. |
| 1646 // TODO(bmeurer): Inline the allocation here to avoid building the frame |
| 1647 // in the fast case? (fall back to AllocateInNewSpace?) |
| 1648 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 1649 __ SmiTag(r3); |
| 1650 __ Push(r3, r4); |
| 1651 __ mr(r3, r6); |
| 1652 ToObjectStub stub(masm->isolate()); |
| 1653 __ CallStub(&stub); |
| 1654 __ mr(r6, r3); |
| 1655 __ Pop(r3, r4); |
| 1656 __ SmiUntag(r3); |
| 1657 } |
| 1658 __ LoadP(r5, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); |
| 1659 __ bind(&convert_receiver); |
1642 } | 1660 } |
1643 __ b(&convert_receiver); | |
1644 __ bind(&convert_to_object); | |
1645 { | |
1646 // Convert receiver using ToObject. | |
1647 // TODO(bmeurer): Inline the allocation here to avoid building the frame | |
1648 // in the fast case? (fall back to AllocateInNewSpace?) | |
1649 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | |
1650 __ SmiTag(r3); | |
1651 __ Push(r3, r4); | |
1652 __ mr(r3, r6); | |
1653 ToObjectStub stub(masm->isolate()); | |
1654 __ CallStub(&stub); | |
1655 __ mr(r6, r3); | |
1656 __ Pop(r3, r4); | |
1657 __ SmiUntag(r3); | |
1658 } | |
1659 __ LoadP(r5, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); | |
1660 __ bind(&convert_receiver); | |
1661 __ ShiftLeftImm(r7, r3, Operand(kPointerSizeLog2)); | 1661 __ ShiftLeftImm(r7, r3, Operand(kPointerSizeLog2)); |
1662 __ StorePX(r6, MemOperand(sp, r7)); | 1662 __ StorePX(r6, MemOperand(sp, r7)); |
1663 } | 1663 } |
1664 __ bind(&done_convert); | 1664 __ bind(&done_convert); |
1665 | 1665 |
1666 // ----------- S t a t e ------------- | 1666 // ----------- S t a t e ------------- |
1667 // -- r3 : the number of arguments (not including the receiver) | 1667 // -- r3 : the number of arguments (not including the receiver) |
1668 // -- r4 : the function to call (checked to be a JSFunction) | 1668 // -- r4 : the function to call (checked to be a JSFunction) |
1669 // -- r5 : the shared function info. | 1669 // -- r5 : the shared function info. |
1670 // -- cp : the function context. | 1670 // -- cp : the function context. |
1671 // ----------------------------------- | 1671 // ----------------------------------- |
1672 | 1672 |
1673 __ LoadWordArith( | 1673 __ LoadWordArith( |
1674 r5, FieldMemOperand(r5, SharedFunctionInfo::kFormalParameterCountOffset)); | 1674 r5, FieldMemOperand(r5, SharedFunctionInfo::kFormalParameterCountOffset)); |
1675 #if !V8_TARGET_ARCH_PPC64 | 1675 #if !V8_TARGET_ARCH_PPC64 |
1676 __ SmiUntag(r5); | 1676 __ SmiUntag(r5); |
1677 #endif | 1677 #endif |
1678 __ LoadP(r6, FieldMemOperand(r4, JSFunction::kCodeEntryOffset)); | 1678 __ LoadP(r6, FieldMemOperand(r4, JSFunction::kCodeEntryOffset)); |
1679 ParameterCount actual(r3); | 1679 ParameterCount actual(r3); |
1680 ParameterCount expected(r5); | 1680 ParameterCount expected(r5); |
1681 __ InvokeCode(r6, expected, actual, JUMP_FUNCTION, NullCallWrapper()); | 1681 __ InvokeCode(r6, expected, actual, JUMP_FUNCTION, NullCallWrapper()); |
| 1682 |
| 1683 // The function is a "classConstructor", need to raise an exception. |
| 1684 __ bind(&class_constructor); |
| 1685 { |
| 1686 FrameAndConstantPoolScope frame(masm, StackFrame::INTERNAL); |
| 1687 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0); |
| 1688 } |
1682 } | 1689 } |
1683 | 1690 |
1684 | 1691 |
1685 // static | 1692 // static |
1686 void Builtins::Generate_Call(MacroAssembler* masm) { | 1693 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { |
1687 // ----------- S t a t e ------------- | 1694 // ----------- S t a t e ------------- |
1688 // -- r3 : the number of arguments (not including the receiver) | 1695 // -- r3 : the number of arguments (not including the receiver) |
1689 // -- r4 : the target to call (can be any Object). | 1696 // -- r4 : the target to call (can be any Object). |
1690 // ----------------------------------- | 1697 // ----------------------------------- |
1691 | 1698 |
1692 Label non_callable, non_function, non_smi; | 1699 Label non_callable, non_function, non_smi; |
1693 __ JumpIfSmi(r4, &non_callable); | 1700 __ JumpIfSmi(r4, &non_callable); |
1694 __ bind(&non_smi); | 1701 __ bind(&non_smi); |
1695 __ CompareObjectType(r4, r7, r8, JS_FUNCTION_TYPE); | 1702 __ CompareObjectType(r4, r7, r8, JS_FUNCTION_TYPE); |
1696 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET, | 1703 __ Jump(masm->isolate()->builtins()->CallFunction(mode), |
1697 eq); | 1704 RelocInfo::CODE_TARGET, eq); |
1698 __ cmpi(r8, Operand(JS_FUNCTION_PROXY_TYPE)); | 1705 __ cmpi(r8, Operand(JS_FUNCTION_PROXY_TYPE)); |
1699 __ bne(&non_function); | 1706 __ bne(&non_function); |
1700 | 1707 |
1701 // 1. Call to function proxy. | 1708 // 1. Call to function proxy. |
1702 // TODO(neis): This doesn't match the ES6 spec for [[Call]] on proxies. | 1709 // TODO(neis): This doesn't match the ES6 spec for [[Call]] on proxies. |
1703 __ LoadP(r4, FieldMemOperand(r4, JSFunctionProxy::kCallTrapOffset)); | 1710 __ LoadP(r4, FieldMemOperand(r4, JSFunctionProxy::kCallTrapOffset)); |
1704 __ AssertNotSmi(r4); | 1711 __ AssertNotSmi(r4); |
1705 __ b(&non_smi); | 1712 __ b(&non_smi); |
1706 | 1713 |
1707 // 2. Call to something else, which might have a [[Call]] internal method (if | 1714 // 2. Call to something else, which might have a [[Call]] internal method (if |
1708 // not we raise an exception). | 1715 // not we raise an exception). |
1709 __ bind(&non_function); | 1716 __ bind(&non_function); |
1710 // Check if target has a [[Call]] internal method. | 1717 // Check if target has a [[Call]] internal method. |
1711 __ lbz(r7, FieldMemOperand(r7, Map::kBitFieldOffset)); | 1718 __ lbz(r7, FieldMemOperand(r7, Map::kBitFieldOffset)); |
1712 __ TestBit(r7, Map::kIsCallable, r0); | 1719 __ TestBit(r7, Map::kIsCallable, r0); |
1713 __ beq(&non_callable, cr0); | 1720 __ beq(&non_callable, cr0); |
1714 // Overwrite the original receiver the (original) target. | 1721 // Overwrite the original receiver the (original) target. |
1715 __ ShiftLeftImm(r8, r3, Operand(kPointerSizeLog2)); | 1722 __ ShiftLeftImm(r8, r3, Operand(kPointerSizeLog2)); |
1716 __ StorePX(r4, MemOperand(sp, r8)); | 1723 __ StorePX(r4, MemOperand(sp, r8)); |
1717 // Let the "call_as_function_delegate" take care of the rest. | 1724 // Let the "call_as_function_delegate" take care of the rest. |
1718 __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, r4); | 1725 __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, r4); |
1719 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); | 1726 __ Jump(masm->isolate()->builtins()->CallFunction( |
| 1727 ConvertReceiverMode::kNotNullOrUndefined), |
| 1728 RelocInfo::CODE_TARGET); |
1720 | 1729 |
1721 // 3. Call to something that is not callable. | 1730 // 3. Call to something that is not callable. |
1722 __ bind(&non_callable); | 1731 __ bind(&non_callable); |
1723 { | 1732 { |
1724 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 1733 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
1725 __ Push(r4); | 1734 __ Push(r4); |
1726 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); | 1735 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); |
1727 } | 1736 } |
1728 } | 1737 } |
1729 | 1738 |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1964 __ bkpt(0); | 1973 __ bkpt(0); |
1965 } | 1974 } |
1966 } | 1975 } |
1967 | 1976 |
1968 | 1977 |
1969 #undef __ | 1978 #undef __ |
1970 } // namespace internal | 1979 } // namespace internal |
1971 } // namespace v8 | 1980 } // namespace v8 |
1972 | 1981 |
1973 #endif // V8_TARGET_ARCH_PPC | 1982 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |