| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
| 6 | 6 |
| 7 #include "src/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
| 8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
| 9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
| 10 #include "src/deoptimizer.h" | 10 #include "src/deoptimizer.h" |
| (...skipping 1536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1547 __ Ldr(x10, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + | 1547 __ Ldr(x10, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + |
| 1548 kPointerSize))); | 1548 kPointerSize))); |
| 1549 __ Mov(jssp, fp); | 1549 __ Mov(jssp, fp); |
| 1550 __ Pop(fp, lr); | 1550 __ Pop(fp, lr); |
| 1551 __ DropBySMI(x10, kXRegSize); | 1551 __ DropBySMI(x10, kXRegSize); |
| 1552 __ Drop(1); | 1552 __ Drop(1); |
| 1553 } | 1553 } |
| 1554 | 1554 |
| 1555 | 1555 |
| 1556 // static | 1556 // static |
| 1557 void Builtins::Generate_CallFunction(MacroAssembler* masm) { | 1557 void Builtins::Generate_CallFunction(MacroAssembler* masm, |
| 1558 ConvertReceiverMode mode) { |
| 1558 // ----------- S t a t e ------------- | 1559 // ----------- S t a t e ------------- |
| 1559 // -- x0 : the number of arguments (not including the receiver) | 1560 // -- x0 : the number of arguments (not including the receiver) |
| 1560 // -- x1 : the function to call (checked to be a JSFunction) | 1561 // -- x1 : the function to call (checked to be a JSFunction) |
| 1561 // ----------------------------------- | 1562 // ----------------------------------- |
| 1562 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) | |
| 1563 | |
| 1564 Label convert, convert_global_proxy, convert_to_object, done_convert; | |
| 1565 __ AssertFunction(x1); | 1563 __ AssertFunction(x1); |
| 1566 | 1564 |
| 1565 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) |
| 1566 // Check that function is not a "classConstructor". |
| 1567 Label class_constructor; |
| 1567 __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); | 1568 __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); |
| 1568 { | 1569 __ Ldr(w3, FieldMemOperand(x2, SharedFunctionInfo::kCompilerHintsOffset)); |
| 1569 Label non_class_constructor; | 1570 __ TestAndBranchIfAnySet( |
| 1570 // Check whether the current function is a classConstructor | 1571 w3, (1 << SharedFunctionInfo::kIsDefaultConstructor) | |
| 1571 __ Ldr(w3, FieldMemOperand(x2, SharedFunctionInfo::kCompilerHintsOffset)); | 1572 (1 << SharedFunctionInfo::kIsSubclassConstructor) | |
| 1572 __ TestAndBranchIfAllClear( | 1573 (1 << SharedFunctionInfo::kIsBaseConstructor), |
| 1573 w3, (1 << SharedFunctionInfo::kIsDefaultConstructor) | | 1574 &class_constructor); |
| 1574 (1 << SharedFunctionInfo::kIsSubclassConstructor) | | |
| 1575 (1 << SharedFunctionInfo::kIsBaseConstructor), | |
| 1576 &non_class_constructor); | |
| 1577 // Step: 2, If we call a classConstructor Function throw a TypeError. | |
| 1578 { | |
| 1579 FrameScope frame(masm, StackFrame::INTERNAL); | |
| 1580 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0); | |
| 1581 } | |
| 1582 __ bind(&non_class_constructor); | |
| 1583 } | |
| 1584 | 1575 |
| 1585 // Enter the context of the function; ToObject has to run in the function | 1576 // Enter the context of the function; ToObject has to run in the function |
| 1586 // context, and we also need to take the global proxy from the function | 1577 // context, and we also need to take the global proxy from the function |
| 1587 // context in case of conversion. | 1578 // context in case of conversion. |
| 1588 __ Ldr(cp, FieldMemOperand(x1, JSFunction::kContextOffset)); | 1579 __ Ldr(cp, FieldMemOperand(x1, JSFunction::kContextOffset)); |
| 1589 // We need to convert the receiver for non-native sloppy mode functions. | 1580 // We need to convert the receiver for non-native sloppy mode functions. |
| 1581 Label done_convert; |
| 1590 __ TestAndBranchIfAnySet(w3, | 1582 __ TestAndBranchIfAnySet(w3, |
| 1591 (1 << SharedFunctionInfo::kNative) | | 1583 (1 << SharedFunctionInfo::kNative) | |
| 1592 (1 << SharedFunctionInfo::kStrictModeFunction), | 1584 (1 << SharedFunctionInfo::kStrictModeFunction), |
| 1593 &done_convert); | 1585 &done_convert); |
| 1594 { | 1586 { |
| 1595 __ Peek(x3, Operand(x0, LSL, kXRegSizeLog2)); | |
| 1596 | |
| 1597 // ----------- S t a t e ------------- | 1587 // ----------- S t a t e ------------- |
| 1598 // -- x0 : the number of arguments (not including the receiver) | 1588 // -- x0 : the number of arguments (not including the receiver) |
| 1599 // -- x1 : the function to call (checked to be a JSFunction) | 1589 // -- x1 : the function to call (checked to be a JSFunction) |
| 1600 // -- x2 : the shared function info. | 1590 // -- x2 : the shared function info. |
| 1601 // -- x3 : the receiver | |
| 1602 // -- cp : the function context. | 1591 // -- cp : the function context. |
| 1603 // ----------------------------------- | 1592 // ----------------------------------- |
| 1604 | 1593 |
| 1605 Label convert_receiver; | 1594 if (mode == ConvertReceiverMode::kNullOrUndefined) { |
| 1606 __ JumpIfSmi(x3, &convert_to_object); | |
| 1607 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); | |
| 1608 __ CompareObjectType(x3, x4, x4, FIRST_JS_RECEIVER_TYPE); | |
| 1609 __ B(hs, &done_convert); | |
| 1610 __ JumpIfRoot(x3, Heap::kUndefinedValueRootIndex, &convert_global_proxy); | |
| 1611 __ JumpIfNotRoot(x3, Heap::kNullValueRootIndex, &convert_to_object); | |
| 1612 __ Bind(&convert_global_proxy); | |
| 1613 { | |
| 1614 // Patch receiver to global proxy. | 1595 // Patch receiver to global proxy. |
| 1615 __ LoadGlobalProxy(x3); | 1596 __ LoadGlobalProxy(x3); |
| 1597 } else { |
| 1598 Label convert_to_object, convert_receiver; |
| 1599 __ Peek(x3, Operand(x0, LSL, kXRegSizeLog2)); |
| 1600 __ JumpIfSmi(x3, &convert_to_object); |
| 1601 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
| 1602 __ CompareObjectType(x3, x4, x4, FIRST_JS_RECEIVER_TYPE); |
| 1603 __ B(hs, &done_convert); |
| 1604 if (mode != ConvertReceiverMode::kNotNullOrUndefined) { |
| 1605 Label convert_global_proxy; |
| 1606 __ JumpIfRoot(x3, Heap::kUndefinedValueRootIndex, |
| 1607 &convert_global_proxy); |
| 1608 __ JumpIfNotRoot(x3, Heap::kNullValueRootIndex, &convert_to_object); |
| 1609 __ Bind(&convert_global_proxy); |
| 1610 { |
| 1611 // Patch receiver to global proxy. |
| 1612 __ LoadGlobalProxy(x3); |
| 1613 } |
| 1614 __ B(&convert_receiver); |
| 1615 } |
| 1616 __ Bind(&convert_to_object); |
| 1617 { |
| 1618 // Convert receiver using ToObject. |
| 1619 // TODO(bmeurer): Inline the allocation here to avoid building the frame |
| 1620 // in the fast case? (fall back to AllocateInNewSpace?) |
| 1621 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1622 __ SmiTag(x0); |
| 1623 __ Push(x0, x1); |
| 1624 __ Mov(x0, x3); |
| 1625 ToObjectStub stub(masm->isolate()); |
| 1626 __ CallStub(&stub); |
| 1627 __ Mov(x3, x0); |
| 1628 __ Pop(x1, x0); |
| 1629 __ SmiUntag(x0); |
| 1630 } |
| 1631 __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); |
| 1632 __ Bind(&convert_receiver); |
| 1616 } | 1633 } |
| 1617 __ B(&convert_receiver); | |
| 1618 __ Bind(&convert_to_object); | |
| 1619 { | |
| 1620 // Convert receiver using ToObject. | |
| 1621 // TODO(bmeurer): Inline the allocation here to avoid building the frame | |
| 1622 // in the fast case? (fall back to AllocateInNewSpace?) | |
| 1623 FrameScope scope(masm, StackFrame::INTERNAL); | |
| 1624 __ SmiTag(x0); | |
| 1625 __ Push(x0, x1); | |
| 1626 __ Mov(x0, x3); | |
| 1627 ToObjectStub stub(masm->isolate()); | |
| 1628 __ CallStub(&stub); | |
| 1629 __ Mov(x3, x0); | |
| 1630 __ Pop(x1, x0); | |
| 1631 __ SmiUntag(x0); | |
| 1632 } | |
| 1633 __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); | |
| 1634 __ Bind(&convert_receiver); | |
| 1635 __ Poke(x3, Operand(x0, LSL, kXRegSizeLog2)); | 1634 __ Poke(x3, Operand(x0, LSL, kXRegSizeLog2)); |
| 1636 } | 1635 } |
| 1637 __ Bind(&done_convert); | 1636 __ Bind(&done_convert); |
| 1638 | 1637 |
| 1639 // ----------- S t a t e ------------- | 1638 // ----------- S t a t e ------------- |
| 1640 // -- x0 : the number of arguments (not including the receiver) | 1639 // -- x0 : the number of arguments (not including the receiver) |
| 1641 // -- x1 : the function to call (checked to be a JSFunction) | 1640 // -- x1 : the function to call (checked to be a JSFunction) |
| 1642 // -- x2 : the shared function info. | 1641 // -- x2 : the shared function info. |
| 1643 // -- cp : the function context. | 1642 // -- cp : the function context. |
| 1644 // ----------------------------------- | 1643 // ----------------------------------- |
| 1645 | 1644 |
| 1646 __ Ldrsw( | 1645 __ Ldrsw( |
| 1647 x2, FieldMemOperand(x2, SharedFunctionInfo::kFormalParameterCountOffset)); | 1646 x2, FieldMemOperand(x2, SharedFunctionInfo::kFormalParameterCountOffset)); |
| 1648 __ Ldr(x3, FieldMemOperand(x1, JSFunction::kCodeEntryOffset)); | 1647 __ Ldr(x3, FieldMemOperand(x1, JSFunction::kCodeEntryOffset)); |
| 1649 ParameterCount actual(x0); | 1648 ParameterCount actual(x0); |
| 1650 ParameterCount expected(x2); | 1649 ParameterCount expected(x2); |
| 1651 __ InvokeCode(x3, expected, actual, JUMP_FUNCTION, NullCallWrapper()); | 1650 __ InvokeCode(x3, expected, actual, JUMP_FUNCTION, NullCallWrapper()); |
| 1651 |
| 1652 // The function is a "classConstructor", need to raise an exception. |
| 1653 __ bind(&class_constructor); |
| 1654 { |
| 1655 FrameScope frame(masm, StackFrame::INTERNAL); |
| 1656 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0); |
| 1657 } |
| 1652 } | 1658 } |
| 1653 | 1659 |
| 1654 | 1660 |
| 1655 // static | 1661 // static |
| 1656 void Builtins::Generate_Call(MacroAssembler* masm) { | 1662 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { |
| 1657 // ----------- S t a t e ------------- | 1663 // ----------- S t a t e ------------- |
| 1658 // -- x0 : the number of arguments (not including the receiver) | 1664 // -- x0 : the number of arguments (not including the receiver) |
| 1659 // -- x1 : the target to call (can be any Object). | 1665 // -- x1 : the target to call (can be any Object). |
| 1660 // ----------------------------------- | 1666 // ----------------------------------- |
| 1661 | 1667 |
| 1662 Label non_callable, non_function, non_smi; | 1668 Label non_callable, non_function, non_smi; |
| 1663 __ JumpIfSmi(x1, &non_callable); | 1669 __ JumpIfSmi(x1, &non_callable); |
| 1664 __ Bind(&non_smi); | 1670 __ Bind(&non_smi); |
| 1665 __ CompareObjectType(x1, x4, x5, JS_FUNCTION_TYPE); | 1671 __ CompareObjectType(x1, x4, x5, JS_FUNCTION_TYPE); |
| 1666 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET, | 1672 __ Jump(masm->isolate()->builtins()->CallFunction(mode), |
| 1667 eq); | 1673 RelocInfo::CODE_TARGET, eq); |
| 1668 __ Cmp(x5, JS_FUNCTION_PROXY_TYPE); | 1674 __ Cmp(x5, JS_FUNCTION_PROXY_TYPE); |
| 1669 __ B(ne, &non_function); | 1675 __ B(ne, &non_function); |
| 1670 | 1676 |
| 1671 // 1. Call to function proxy. | 1677 // 1. Call to function proxy. |
| 1672 // TODO(neis): This doesn't match the ES6 spec for [[Call]] on proxies. | 1678 // TODO(neis): This doesn't match the ES6 spec for [[Call]] on proxies. |
| 1673 __ Ldr(x1, FieldMemOperand(x1, JSFunctionProxy::kCallTrapOffset)); | 1679 __ Ldr(x1, FieldMemOperand(x1, JSFunctionProxy::kCallTrapOffset)); |
| 1674 __ AssertNotSmi(x1); | 1680 __ AssertNotSmi(x1); |
| 1675 __ B(&non_smi); | 1681 __ B(&non_smi); |
| 1676 | 1682 |
| 1677 // 2. Call to something else, which might have a [[Call]] internal method (if | 1683 // 2. Call to something else, which might have a [[Call]] internal method (if |
| 1678 // not we raise an exception). | 1684 // not we raise an exception). |
| 1679 __ Bind(&non_function); | 1685 __ Bind(&non_function); |
| 1680 // Check if target has a [[Call]] internal method. | 1686 // Check if target has a [[Call]] internal method. |
| 1681 __ Ldrb(x4, FieldMemOperand(x4, Map::kBitFieldOffset)); | 1687 __ Ldrb(x4, FieldMemOperand(x4, Map::kBitFieldOffset)); |
| 1682 __ TestAndBranchIfAllClear(x4, 1 << Map::kIsCallable, &non_callable); | 1688 __ TestAndBranchIfAllClear(x4, 1 << Map::kIsCallable, &non_callable); |
| 1683 // Overwrite the original receiver with the (original) target. | 1689 // Overwrite the original receiver with the (original) target. |
| 1684 __ Poke(x1, Operand(x0, LSL, kXRegSizeLog2)); | 1690 __ Poke(x1, Operand(x0, LSL, kXRegSizeLog2)); |
| 1685 // Let the "call_as_function_delegate" take care of the rest. | 1691 // Let the "call_as_function_delegate" take care of the rest. |
| 1686 __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, x1); | 1692 __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, x1); |
| 1687 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); | 1693 __ Jump(masm->isolate()->builtins()->CallFunction( |
| 1694 ConvertReceiverMode::kNotNullOrUndefined), |
| 1695 RelocInfo::CODE_TARGET); |
| 1688 | 1696 |
| 1689 // 3. Call to something that is not callable. | 1697 // 3. Call to something that is not callable. |
| 1690 __ bind(&non_callable); | 1698 __ bind(&non_callable); |
| 1691 { | 1699 { |
| 1692 FrameScope scope(masm, StackFrame::INTERNAL); | 1700 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1693 __ Push(x1); | 1701 __ Push(x1); |
| 1694 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); | 1702 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); |
| 1695 } | 1703 } |
| 1696 } | 1704 } |
| 1697 | 1705 |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2017 } | 2025 } |
| 2018 } | 2026 } |
| 2019 | 2027 |
| 2020 | 2028 |
| 2021 #undef __ | 2029 #undef __ |
| 2022 | 2030 |
| 2023 } // namespace internal | 2031 } // namespace internal |
| 2024 } // namespace v8 | 2032 } // namespace v8 |
| 2025 | 2033 |
| 2026 #endif // V8_TARGET_ARCH_ARM | 2034 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |