| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_MIPS64 | 5 #if V8_TARGET_ARCH_MIPS64 |
| 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 1548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1559 __ mov(sp, fp); | 1559 __ mov(sp, fp); |
| 1560 __ MultiPop(fp.bit() | ra.bit()); | 1560 __ MultiPop(fp.bit() | ra.bit()); |
| 1561 __ SmiScale(a4, a1, kPointerSizeLog2); | 1561 __ SmiScale(a4, a1, kPointerSizeLog2); |
| 1562 __ Daddu(sp, sp, a4); | 1562 __ Daddu(sp, sp, a4); |
| 1563 // Adjust for the receiver. | 1563 // Adjust for the receiver. |
| 1564 __ Daddu(sp, sp, Operand(kPointerSize)); | 1564 __ Daddu(sp, sp, Operand(kPointerSize)); |
| 1565 } | 1565 } |
| 1566 | 1566 |
| 1567 | 1567 |
| 1568 // static | 1568 // static |
| 1569 void Builtins::Generate_CallFunction(MacroAssembler* masm) { | 1569 void Builtins::Generate_CallFunction(MacroAssembler* masm, |
| 1570 ConvertReceiverMode mode) { |
| 1570 // ----------- S t a t e ------------- | 1571 // ----------- S t a t e ------------- |
| 1571 // -- a0 : the number of arguments (not including the receiver) | 1572 // -- a0 : the number of arguments (not including the receiver) |
| 1572 // -- a1 : the function to call (checked to be a JSFunction) | 1573 // -- a1 : the function to call (checked to be a JSFunction) |
| 1573 // ----------------------------------- | 1574 // ----------------------------------- |
| 1575 __ AssertFunction(a1); |
| 1574 | 1576 |
| 1575 Label convert, convert_global_proxy, convert_to_object, done_convert; | 1577 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) |
| 1576 __ AssertFunction(a1); | 1578 // Check that function is not a "classConstructor". |
| 1579 Label class_constructor; |
| 1577 __ ld(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 1580 __ ld(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
| 1578 | 1581 __ lbu(a3, FieldMemOperand(a2, SharedFunctionInfo::kFunctionKindByteOffset)); |
| 1579 { | 1582 __ And(at, a3, Operand(SharedFunctionInfo::kClassConstructorBitsWithinByte)); |
| 1580 Label non_class_constructor; | 1583 __ Branch(&class_constructor, ne, at, Operand(zero_reg)); |
| 1581 // Check whether the current function is a classConstructor | |
| 1582 __ lbu(a3, | |
| 1583 FieldMemOperand(a2, SharedFunctionInfo::kFunctionKindByteOffset)); | |
| 1584 __ And(at, a3, | |
| 1585 Operand(SharedFunctionInfo::kClassConstructorBitsWithinByte)); | |
| 1586 __ Branch(&non_class_constructor, eq, at, Operand(zero_reg)); | |
| 1587 // Step: 2, If we call a classConstructor Function throw a TypeError. | |
| 1588 { | |
| 1589 FrameScope frame(masm, StackFrame::INTERNAL); | |
| 1590 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0); | |
| 1591 } | |
| 1592 __ bind(&non_class_constructor); | |
| 1593 } | |
| 1594 | 1584 |
| 1595 // Enter the context of the function; ToObject has to run in the function | 1585 // Enter the context of the function; ToObject has to run in the function |
| 1596 // context, and we also need to take the global proxy from the function | 1586 // context, and we also need to take the global proxy from the function |
| 1597 // context in case of conversion. | 1587 // context in case of conversion. |
| 1598 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) | |
| 1599 STATIC_ASSERT(SharedFunctionInfo::kNativeByteOffset == | 1588 STATIC_ASSERT(SharedFunctionInfo::kNativeByteOffset == |
| 1600 SharedFunctionInfo::kStrictModeByteOffset); | 1589 SharedFunctionInfo::kStrictModeByteOffset); |
| 1601 __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 1590 __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
| 1602 // We need to convert the receiver for non-native sloppy mode functions. | 1591 // We need to convert the receiver for non-native sloppy mode functions. |
| 1592 Label done_convert; |
| 1603 __ lbu(a3, FieldMemOperand(a2, SharedFunctionInfo::kNativeByteOffset)); | 1593 __ lbu(a3, FieldMemOperand(a2, SharedFunctionInfo::kNativeByteOffset)); |
| 1604 __ And(at, a3, Operand((1 << SharedFunctionInfo::kNativeBitWithinByte) | | 1594 __ And(at, a3, Operand((1 << SharedFunctionInfo::kNativeBitWithinByte) | |
| 1605 (1 << SharedFunctionInfo::kStrictModeBitWithinByte))); | 1595 (1 << SharedFunctionInfo::kStrictModeBitWithinByte))); |
| 1606 __ Branch(&done_convert, ne, at, Operand(zero_reg)); | 1596 __ Branch(&done_convert, ne, at, Operand(zero_reg)); |
| 1607 { | 1597 { |
| 1608 __ dsll(at, a0, kPointerSizeLog2); | |
| 1609 __ daddu(at, sp, at); | |
| 1610 __ ld(a3, MemOperand(at)); | |
| 1611 | |
| 1612 // ----------- S t a t e ------------- | 1598 // ----------- S t a t e ------------- |
| 1613 // -- a0 : the number of arguments (not including the receiver) | 1599 // -- a0 : the number of arguments (not including the receiver) |
| 1614 // -- a1 : the function to call (checked to be a JSFunction) | 1600 // -- a1 : the function to call (checked to be a JSFunction) |
| 1615 // -- a2 : the shared function info. | 1601 // -- a2 : the shared function info. |
| 1616 // -- a3 : the receiver | |
| 1617 // -- cp : the function context. | 1602 // -- cp : the function context. |
| 1618 // ----------------------------------- | 1603 // ----------------------------------- |
| 1619 | 1604 |
| 1620 Label convert_receiver; | 1605 if (mode == ConvertReceiverMode::kNullOrUndefined) { |
| 1621 __ JumpIfSmi(a3, &convert_to_object); | |
| 1622 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); | |
| 1623 __ GetObjectType(a3, a4, a4); | |
| 1624 __ Branch(&done_convert, hs, a4, Operand(FIRST_JS_RECEIVER_TYPE)); | |
| 1625 __ JumpIfRoot(a3, Heap::kUndefinedValueRootIndex, &convert_global_proxy); | |
| 1626 __ JumpIfNotRoot(a3, Heap::kNullValueRootIndex, &convert_to_object); | |
| 1627 __ bind(&convert_global_proxy); | |
| 1628 { | |
| 1629 // Patch receiver to global proxy. | 1606 // Patch receiver to global proxy. |
| 1630 __ LoadGlobalProxy(a3); | 1607 __ LoadGlobalProxy(a3); |
| 1608 } else { |
| 1609 Label convert_to_object, convert_receiver; |
| 1610 __ dsll(at, a0, kPointerSizeLog2); |
| 1611 __ daddu(at, sp, at); |
| 1612 __ ld(a3, MemOperand(at)); |
| 1613 __ JumpIfSmi(a3, &convert_to_object); |
| 1614 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
| 1615 __ GetObjectType(a3, a4, a4); |
| 1616 __ Branch(&done_convert, hs, a4, Operand(FIRST_JS_RECEIVER_TYPE)); |
| 1617 if (mode != ConvertReceiverMode::kNotNullOrUndefined) { |
| 1618 Label convert_global_proxy; |
| 1619 __ JumpIfRoot(a3, Heap::kUndefinedValueRootIndex, |
| 1620 &convert_global_proxy); |
| 1621 __ JumpIfNotRoot(a3, Heap::kNullValueRootIndex, &convert_to_object); |
| 1622 __ bind(&convert_global_proxy); |
| 1623 { |
| 1624 // Patch receiver to global proxy. |
| 1625 __ LoadGlobalProxy(a3); |
| 1626 } |
| 1627 __ Branch(&convert_receiver); |
| 1628 } |
| 1629 __ bind(&convert_to_object); |
| 1630 { |
| 1631 // Convert receiver using ToObject. |
| 1632 // TODO(bmeurer): Inline the allocation here to avoid building the frame |
| 1633 // in the fast case? (fall back to AllocateInNewSpace?) |
| 1634 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1635 __ SmiTag(a0); |
| 1636 __ Push(a0, a1); |
| 1637 __ mov(a0, a3); |
| 1638 ToObjectStub stub(masm->isolate()); |
| 1639 __ CallStub(&stub); |
| 1640 __ mov(a3, v0); |
| 1641 __ Pop(a0, a1); |
| 1642 __ SmiUntag(a0); |
| 1643 } |
| 1644 __ ld(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
| 1645 __ bind(&convert_receiver); |
| 1631 } | 1646 } |
| 1632 __ Branch(&convert_receiver); | |
| 1633 __ bind(&convert_to_object); | |
| 1634 { | |
| 1635 // Convert receiver using ToObject. | |
| 1636 // TODO(bmeurer): Inline the allocation here to avoid building the frame | |
| 1637 // in the fast case? (fall back to AllocateInNewSpace?) | |
| 1638 FrameScope scope(masm, StackFrame::INTERNAL); | |
| 1639 __ SmiTag(a0); | |
| 1640 __ Push(a0, a1); | |
| 1641 __ mov(a0, a3); | |
| 1642 ToObjectStub stub(masm->isolate()); | |
| 1643 __ CallStub(&stub); | |
| 1644 __ mov(a3, v0); | |
| 1645 __ Pop(a0, a1); | |
| 1646 __ SmiUntag(a0); | |
| 1647 } | |
| 1648 __ ld(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | |
| 1649 __ bind(&convert_receiver); | |
| 1650 __ dsll(at, a0, kPointerSizeLog2); | 1647 __ dsll(at, a0, kPointerSizeLog2); |
| 1651 __ daddu(at, sp, at); | 1648 __ daddu(at, sp, at); |
| 1652 __ sd(a3, MemOperand(at)); | 1649 __ sd(a3, MemOperand(at)); |
| 1653 } | 1650 } |
| 1654 __ bind(&done_convert); | 1651 __ bind(&done_convert); |
| 1655 | 1652 |
| 1656 // ----------- S t a t e ------------- | 1653 // ----------- S t a t e ------------- |
| 1657 // -- a0 : the number of arguments (not including the receiver) | 1654 // -- a0 : the number of arguments (not including the receiver) |
| 1658 // -- a1 : the function to call (checked to be a JSFunction) | 1655 // -- a1 : the function to call (checked to be a JSFunction) |
| 1659 // -- a2 : the shared function info. | 1656 // -- a2 : the shared function info. |
| 1660 // -- cp : the function context. | 1657 // -- cp : the function context. |
| 1661 // ----------------------------------- | 1658 // ----------------------------------- |
| 1662 | 1659 |
| 1663 __ lw(a2, | 1660 __ lw(a2, |
| 1664 FieldMemOperand(a2, SharedFunctionInfo::kFormalParameterCountOffset)); | 1661 FieldMemOperand(a2, SharedFunctionInfo::kFormalParameterCountOffset)); |
| 1665 __ ld(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 1662 __ ld(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
| 1666 ParameterCount actual(a0); | 1663 ParameterCount actual(a0); |
| 1667 ParameterCount expected(a2); | 1664 ParameterCount expected(a2); |
| 1668 __ InvokeCode(a3, expected, actual, JUMP_FUNCTION, NullCallWrapper()); | 1665 __ InvokeCode(a3, expected, actual, JUMP_FUNCTION, NullCallWrapper()); |
| 1666 |
| 1667 // The function is a "classConstructor", need to raise an exception. |
| 1668 __ bind(&class_constructor); |
| 1669 { |
| 1670 FrameScope frame(masm, StackFrame::INTERNAL); |
| 1671 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0); |
| 1672 } |
| 1669 } | 1673 } |
| 1670 | 1674 |
| 1671 | 1675 |
| 1672 // static | 1676 // static |
| 1673 void Builtins::Generate_Call(MacroAssembler* masm) { | 1677 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { |
| 1674 // ----------- S t a t e ------------- | 1678 // ----------- S t a t e ------------- |
| 1675 // -- a0 : the number of arguments (not including the receiver) | 1679 // -- a0 : the number of arguments (not including the receiver) |
| 1676 // -- a1 : the target to call (can be any Object). | 1680 // -- a1 : the target to call (can be any Object). |
| 1677 // ----------------------------------- | 1681 // ----------------------------------- |
| 1678 | 1682 |
| 1679 Label non_callable, non_function, non_smi; | 1683 Label non_callable, non_function, non_smi; |
| 1680 __ JumpIfSmi(a1, &non_callable); | 1684 __ JumpIfSmi(a1, &non_callable); |
| 1681 __ bind(&non_smi); | 1685 __ bind(&non_smi); |
| 1682 __ GetObjectType(a1, t1, t2); | 1686 __ GetObjectType(a1, t1, t2); |
| 1683 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET, | 1687 __ Jump(masm->isolate()->builtins()->CallFunction(mode), |
| 1684 eq, t2, Operand(JS_FUNCTION_TYPE)); | 1688 RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE)); |
| 1685 __ Branch(&non_function, ne, t2, Operand(JS_FUNCTION_PROXY_TYPE)); | 1689 __ Branch(&non_function, ne, t2, Operand(JS_FUNCTION_PROXY_TYPE)); |
| 1686 | 1690 |
| 1687 // 1. Call to function proxy. | 1691 // 1. Call to function proxy. |
| 1688 // TODO(neis): This doesn't match the ES6 spec for [[Call]] on proxies. | 1692 // TODO(neis): This doesn't match the ES6 spec for [[Call]] on proxies. |
| 1689 __ ld(a1, FieldMemOperand(a1, JSFunctionProxy::kCallTrapOffset)); | 1693 __ ld(a1, FieldMemOperand(a1, JSFunctionProxy::kCallTrapOffset)); |
| 1690 __ AssertNotSmi(a1); | 1694 __ AssertNotSmi(a1); |
| 1691 __ Branch(&non_smi); | 1695 __ Branch(&non_smi); |
| 1692 | 1696 |
| 1693 // 2. Call to something else, which might have a [[Call]] internal method (if | 1697 // 2. Call to something else, which might have a [[Call]] internal method (if |
| 1694 // not we raise an exception). | 1698 // not we raise an exception). |
| 1695 __ bind(&non_function); | 1699 __ bind(&non_function); |
| 1696 // Check if target has a [[Call]] internal method. | 1700 // Check if target has a [[Call]] internal method. |
| 1697 __ lbu(t1, FieldMemOperand(t1, Map::kBitFieldOffset)); | 1701 __ lbu(t1, FieldMemOperand(t1, Map::kBitFieldOffset)); |
| 1698 __ And(t1, t1, Operand(1 << Map::kIsCallable)); | 1702 __ And(t1, t1, Operand(1 << Map::kIsCallable)); |
| 1699 __ Branch(&non_callable, eq, t1, Operand(zero_reg)); | 1703 __ Branch(&non_callable, eq, t1, Operand(zero_reg)); |
| 1700 // Overwrite the original receiver with the (original) target. | 1704 // Overwrite the original receiver with the (original) target. |
| 1701 __ dsll(at, a0, kPointerSizeLog2); | 1705 __ dsll(at, a0, kPointerSizeLog2); |
| 1702 __ daddu(at, sp, at); | 1706 __ daddu(at, sp, at); |
| 1703 __ sd(a1, MemOperand(at)); | 1707 __ sd(a1, MemOperand(at)); |
| 1704 // Let the "call_as_function_delegate" take care of the rest. | 1708 // Let the "call_as_function_delegate" take care of the rest. |
| 1705 __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, a1); | 1709 __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, a1); |
| 1706 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); | 1710 __ Jump(masm->isolate()->builtins()->CallFunction( |
| 1711 ConvertReceiverMode::kNotNullOrUndefined), |
| 1712 RelocInfo::CODE_TARGET); |
| 1707 | 1713 |
| 1708 // 3. Call to something that is not callable. | 1714 // 3. Call to something that is not callable. |
| 1709 __ bind(&non_callable); | 1715 __ bind(&non_callable); |
| 1710 { | 1716 { |
| 1711 FrameScope scope(masm, StackFrame::INTERNAL); | 1717 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1712 __ Push(a1); | 1718 __ Push(a1); |
| 1713 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); | 1719 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); |
| 1714 } | 1720 } |
| 1715 } | 1721 } |
| 1716 | 1722 |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1951 } | 1957 } |
| 1952 } | 1958 } |
| 1953 | 1959 |
| 1954 | 1960 |
| 1955 #undef __ | 1961 #undef __ |
| 1956 | 1962 |
| 1957 } // namespace internal | 1963 } // namespace internal |
| 1958 } // namespace v8 | 1964 } // namespace v8 |
| 1959 | 1965 |
| 1960 #endif // V8_TARGET_ARCH_MIPS64 | 1966 #endif // V8_TARGET_ARCH_MIPS64 |
| OLD | NEW |