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 |