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_ARM | 5 #if V8_TARGET_ARCH_ARM |
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 1541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1552 __ ldr(r1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + | 1552 __ ldr(r1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + |
1553 kPointerSize))); | 1553 kPointerSize))); |
1554 | 1554 |
1555 __ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR); | 1555 __ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR); |
1556 __ add(sp, sp, Operand::PointerOffsetFromSmiKey(r1)); | 1556 __ add(sp, sp, Operand::PointerOffsetFromSmiKey(r1)); |
1557 __ add(sp, sp, Operand(kPointerSize)); // adjust for receiver | 1557 __ add(sp, sp, Operand(kPointerSize)); // adjust for receiver |
1558 } | 1558 } |
1559 | 1559 |
1560 | 1560 |
1561 // static | 1561 // static |
1562 void Builtins::Generate_CallFunction(MacroAssembler* masm) { | 1562 void Builtins::Generate_CallFunction(MacroAssembler* masm, |
| 1563 ConvertReceiverMode mode) { |
1563 // ----------- S t a t e ------------- | 1564 // ----------- S t a t e ------------- |
1564 // -- r0 : the number of arguments (not including the receiver) | 1565 // -- r0 : the number of arguments (not including the receiver) |
1565 // -- r1 : the function to call (checked to be a JSFunction) | 1566 // -- r1 : the function to call (checked to be a JSFunction) |
1566 // ----------------------------------- | 1567 // ----------------------------------- |
| 1568 __ AssertFunction(r1); |
| 1569 |
1567 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) | 1570 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) |
1568 | 1571 // Check that the function is not a "classConstructor". |
1569 Label convert, convert_global_proxy, convert_to_object, done_convert; | 1572 Label class_constructor; |
1570 __ AssertFunction(r1); | |
1571 __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | 1573 __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
1572 { | 1574 __ ldrb(r3, FieldMemOperand(r2, SharedFunctionInfo::kFunctionKindByteOffset)); |
1573 Label non_class_constructor; | 1575 __ tst(r3, Operand(SharedFunctionInfo::kClassConstructorBitsWithinByte)); |
1574 // Check whether the current function is a classConstructor. | 1576 __ b(ne, &class_constructor); |
1575 __ ldrb(r3, | |
1576 FieldMemOperand(r2, SharedFunctionInfo::kFunctionKindByteOffset)); | |
1577 __ tst(r3, Operand(SharedFunctionInfo::kClassConstructorBitsWithinByte)); | |
1578 __ b(eq, &non_class_constructor); | |
1579 // Step: 2, If we call a classConstructor Function throw a TypeError. | |
1580 { | |
1581 FrameScope frame(masm, StackFrame::INTERNAL); | |
1582 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0); | |
1583 } | |
1584 __ bind(&non_class_constructor); | |
1585 } | |
1586 | 1577 |
1587 // Enter the context of the function; ToObject has to run in the function | 1578 // Enter the context of the function; ToObject has to run in the function |
1588 // context, and we also need to take the global proxy from the function | 1579 // context, and we also need to take the global proxy from the function |
1589 // context in case of conversion. | 1580 // context in case of conversion. |
1590 STATIC_ASSERT(SharedFunctionInfo::kNativeByteOffset == | 1581 STATIC_ASSERT(SharedFunctionInfo::kNativeByteOffset == |
1591 SharedFunctionInfo::kStrictModeByteOffset); | 1582 SharedFunctionInfo::kStrictModeByteOffset); |
1592 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | 1583 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
1593 // We need to convert the receiver for non-native sloppy mode functions. | 1584 // We need to convert the receiver for non-native sloppy mode functions. |
| 1585 Label done_convert; |
1594 __ ldrb(r3, FieldMemOperand(r2, SharedFunctionInfo::kNativeByteOffset)); | 1586 __ ldrb(r3, FieldMemOperand(r2, SharedFunctionInfo::kNativeByteOffset)); |
1595 __ tst(r3, Operand((1 << SharedFunctionInfo::kNativeBitWithinByte) | | 1587 __ tst(r3, Operand((1 << SharedFunctionInfo::kNativeBitWithinByte) | |
1596 (1 << SharedFunctionInfo::kStrictModeBitWithinByte))); | 1588 (1 << SharedFunctionInfo::kStrictModeBitWithinByte))); |
1597 __ b(ne, &done_convert); | 1589 __ b(ne, &done_convert); |
1598 { | 1590 { |
1599 __ ldr(r3, MemOperand(sp, r0, LSL, kPointerSizeLog2)); | |
1600 | |
1601 // ----------- S t a t e ------------- | 1591 // ----------- S t a t e ------------- |
1602 // -- r0 : the number of arguments (not including the receiver) | 1592 // -- r0 : the number of arguments (not including the receiver) |
1603 // -- r1 : the function to call (checked to be a JSFunction) | 1593 // -- r1 : the function to call (checked to be a JSFunction) |
1604 // -- r2 : the shared function info. | 1594 // -- r2 : the shared function info. |
1605 // -- r3 : the receiver | |
1606 // -- cp : the function context. | 1595 // -- cp : the function context. |
1607 // ----------------------------------- | 1596 // ----------------------------------- |
1608 | 1597 |
1609 Label convert_receiver; | 1598 if (mode == ConvertReceiverMode::kNullOrUndefined) { |
1610 __ JumpIfSmi(r3, &convert_to_object); | |
1611 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); | |
1612 __ CompareObjectType(r3, r4, r4, FIRST_JS_RECEIVER_TYPE); | |
1613 __ b(hs, &done_convert); | |
1614 __ JumpIfRoot(r3, Heap::kUndefinedValueRootIndex, &convert_global_proxy); | |
1615 __ JumpIfNotRoot(r3, Heap::kNullValueRootIndex, &convert_to_object); | |
1616 __ bind(&convert_global_proxy); | |
1617 { | |
1618 // Patch receiver to global proxy. | 1599 // Patch receiver to global proxy. |
1619 __ LoadGlobalProxy(r3); | 1600 __ LoadGlobalProxy(r3); |
| 1601 } else { |
| 1602 Label convert_to_object, convert_receiver; |
| 1603 __ ldr(r3, MemOperand(sp, r0, LSL, kPointerSizeLog2)); |
| 1604 __ JumpIfSmi(r3, &convert_to_object); |
| 1605 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
| 1606 __ CompareObjectType(r3, r4, r4, FIRST_JS_RECEIVER_TYPE); |
| 1607 __ b(hs, &done_convert); |
| 1608 if (mode != ConvertReceiverMode::kNotNullOrUndefined) { |
| 1609 Label convert_global_proxy; |
| 1610 __ JumpIfRoot(r3, Heap::kUndefinedValueRootIndex, |
| 1611 &convert_global_proxy); |
| 1612 __ JumpIfNotRoot(r3, Heap::kNullValueRootIndex, &convert_to_object); |
| 1613 __ bind(&convert_global_proxy); |
| 1614 { |
| 1615 // Patch receiver to global proxy. |
| 1616 __ LoadGlobalProxy(r3); |
| 1617 } |
| 1618 __ b(&convert_receiver); |
| 1619 } |
| 1620 __ bind(&convert_to_object); |
| 1621 { |
| 1622 // Convert receiver using ToObject. |
| 1623 // TODO(bmeurer): Inline the allocation here to avoid building the frame |
| 1624 // in the fast case? (fall back to AllocateInNewSpace?) |
| 1625 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 1626 __ SmiTag(r0); |
| 1627 __ Push(r0, r1); |
| 1628 __ mov(r0, r3); |
| 1629 ToObjectStub stub(masm->isolate()); |
| 1630 __ CallStub(&stub); |
| 1631 __ mov(r3, r0); |
| 1632 __ Pop(r0, r1); |
| 1633 __ SmiUntag(r0); |
| 1634 } |
| 1635 __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
| 1636 __ bind(&convert_receiver); |
1620 } | 1637 } |
1621 __ b(&convert_receiver); | |
1622 __ bind(&convert_to_object); | |
1623 { | |
1624 // Convert receiver using ToObject. | |
1625 // TODO(bmeurer): Inline the allocation here to avoid building the frame | |
1626 // in the fast case? (fall back to AllocateInNewSpace?) | |
1627 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | |
1628 __ SmiTag(r0); | |
1629 __ Push(r0, r1); | |
1630 __ mov(r0, r3); | |
1631 ToObjectStub stub(masm->isolate()); | |
1632 __ CallStub(&stub); | |
1633 __ mov(r3, r0); | |
1634 __ Pop(r0, r1); | |
1635 __ SmiUntag(r0); | |
1636 } | |
1637 __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | |
1638 __ bind(&convert_receiver); | |
1639 __ str(r3, MemOperand(sp, r0, LSL, kPointerSizeLog2)); | 1638 __ str(r3, MemOperand(sp, r0, LSL, kPointerSizeLog2)); |
1640 } | 1639 } |
1641 __ bind(&done_convert); | 1640 __ bind(&done_convert); |
1642 | 1641 |
1643 // ----------- S t a t e ------------- | 1642 // ----------- S t a t e ------------- |
1644 // -- r0 : the number of arguments (not including the receiver) | 1643 // -- r0 : the number of arguments (not including the receiver) |
1645 // -- r1 : the function to call (checked to be a JSFunction) | 1644 // -- r1 : the function to call (checked to be a JSFunction) |
1646 // -- r2 : the shared function info. | 1645 // -- r2 : the shared function info. |
1647 // -- cp : the function context. | 1646 // -- cp : the function context. |
1648 // ----------------------------------- | 1647 // ----------------------------------- |
1649 | 1648 |
1650 __ ldr(r2, | 1649 __ ldr(r2, |
1651 FieldMemOperand(r2, SharedFunctionInfo::kFormalParameterCountOffset)); | 1650 FieldMemOperand(r2, SharedFunctionInfo::kFormalParameterCountOffset)); |
1652 __ SmiUntag(r2); | 1651 __ SmiUntag(r2); |
1653 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); | 1652 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); |
1654 ParameterCount actual(r0); | 1653 ParameterCount actual(r0); |
1655 ParameterCount expected(r2); | 1654 ParameterCount expected(r2); |
1656 __ InvokeCode(r3, expected, actual, JUMP_FUNCTION, NullCallWrapper()); | 1655 __ InvokeCode(r3, expected, actual, JUMP_FUNCTION, NullCallWrapper()); |
| 1656 |
| 1657 // The function is a "classConstructor", need to raise an exception. |
| 1658 __ bind(&class_constructor); |
| 1659 { |
| 1660 FrameScope frame(masm, StackFrame::INTERNAL); |
| 1661 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0); |
| 1662 } |
1657 } | 1663 } |
1658 | 1664 |
1659 | 1665 |
1660 // static | 1666 // static |
1661 void Builtins::Generate_Call(MacroAssembler* masm) { | 1667 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { |
1662 // ----------- S t a t e ------------- | 1668 // ----------- S t a t e ------------- |
1663 // -- r0 : the number of arguments (not including the receiver) | 1669 // -- r0 : the number of arguments (not including the receiver) |
1664 // -- r1 : the target to call (can be any Object). | 1670 // -- r1 : the target to call (can be any Object). |
1665 // ----------------------------------- | 1671 // ----------------------------------- |
1666 | 1672 |
1667 Label non_callable, non_function, non_smi; | 1673 Label non_callable, non_function, non_smi; |
1668 __ JumpIfSmi(r1, &non_callable); | 1674 __ JumpIfSmi(r1, &non_callable); |
1669 __ bind(&non_smi); | 1675 __ bind(&non_smi); |
1670 __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE); | 1676 __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE); |
1671 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET, | 1677 __ Jump(masm->isolate()->builtins()->CallFunction(mode), |
1672 eq); | 1678 RelocInfo::CODE_TARGET, eq); |
1673 __ cmp(r5, Operand(JS_FUNCTION_PROXY_TYPE)); | 1679 __ cmp(r5, Operand(JS_FUNCTION_PROXY_TYPE)); |
1674 __ b(ne, &non_function); | 1680 __ b(ne, &non_function); |
1675 | 1681 |
1676 // 1. Call to function proxy. | 1682 // 1. Call to function proxy. |
1677 // TODO(neis): This doesn't match the ES6 spec for [[Call]] on proxies. | 1683 // TODO(neis): This doesn't match the ES6 spec for [[Call]] on proxies. |
1678 __ ldr(r1, FieldMemOperand(r1, JSFunctionProxy::kCallTrapOffset)); | 1684 __ ldr(r1, FieldMemOperand(r1, JSFunctionProxy::kCallTrapOffset)); |
1679 __ AssertNotSmi(r1); | 1685 __ AssertNotSmi(r1); |
1680 __ b(&non_smi); | 1686 __ b(&non_smi); |
1681 | 1687 |
1682 // 2. Call to something else, which might have a [[Call]] internal method (if | 1688 // 2. Call to something else, which might have a [[Call]] internal method (if |
1683 // not we raise an exception). | 1689 // not we raise an exception). |
1684 __ bind(&non_function); | 1690 __ bind(&non_function); |
1685 // Check if target has a [[Call]] internal method. | 1691 // Check if target has a [[Call]] internal method. |
1686 __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset)); | 1692 __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset)); |
1687 __ tst(r4, Operand(1 << Map::kIsCallable)); | 1693 __ tst(r4, Operand(1 << Map::kIsCallable)); |
1688 __ b(eq, &non_callable); | 1694 __ b(eq, &non_callable); |
1689 // Overwrite the original receiver the (original) target. | 1695 // Overwrite the original receiver the (original) target. |
1690 __ str(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); | 1696 __ str(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); |
1691 // Let the "call_as_function_delegate" take care of the rest. | 1697 // Let the "call_as_function_delegate" take care of the rest. |
1692 __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, r1); | 1698 __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, r1); |
1693 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); | 1699 __ Jump(masm->isolate()->builtins()->CallFunction( |
| 1700 ConvertReceiverMode::kNotNullOrUndefined), |
| 1701 RelocInfo::CODE_TARGET); |
1694 | 1702 |
1695 // 3. Call to something that is not callable. | 1703 // 3. Call to something that is not callable. |
1696 __ bind(&non_callable); | 1704 __ bind(&non_callable); |
1697 { | 1705 { |
1698 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 1706 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
1699 __ Push(r1); | 1707 __ Push(r1); |
1700 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); | 1708 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); |
1701 } | 1709 } |
1702 } | 1710 } |
1703 | 1711 |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1928 } | 1936 } |
1929 } | 1937 } |
1930 | 1938 |
1931 | 1939 |
1932 #undef __ | 1940 #undef __ |
1933 | 1941 |
1934 } // namespace internal | 1942 } // namespace internal |
1935 } // namespace v8 | 1943 } // namespace v8 |
1936 | 1944 |
1937 #endif // V8_TARGET_ARCH_ARM | 1945 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |