OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1681 } | 1681 } |
1682 context()->Plug(r0); | 1682 context()->Plug(r0); |
1683 } | 1683 } |
1684 | 1684 |
1685 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 1685 void FullCodeGenerator::EmitCallWithIC(Call* expr, |
1686 Handle<Object> name, | 1686 Handle<Object> name, |
1687 RelocInfo::Mode mode) { | 1687 RelocInfo::Mode mode) { |
1688 // Code common for calls using the IC. | 1688 // Code common for calls using the IC. |
1689 ZoneList<Expression*>* args = expr->arguments(); | 1689 ZoneList<Expression*>* args = expr->arguments(); |
1690 int arg_count = args->length(); | 1690 int arg_count = args->length(); |
1691 for (int i = 0; i < arg_count; i++) { | 1691 { PreserveStatementPositionScope scope(masm()->positions_recorder()); |
1692 VisitForStackValue(args->at(i)); | 1692 for (int i = 0; i < arg_count; i++) { |
| 1693 VisitForStackValue(args->at(i)); |
| 1694 } |
| 1695 __ mov(r2, Operand(name)); |
1693 } | 1696 } |
1694 __ mov(r2, Operand(name)); | |
1695 // Record source position for debugger. | 1697 // Record source position for debugger. |
1696 SetSourcePosition(expr->position()); | 1698 SetSourcePosition(expr->position(), FORCED_POSITION); |
1697 // Call the IC initialization code. | 1699 // Call the IC initialization code. |
1698 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1700 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
1699 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop); | 1701 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop); |
1700 EmitCallIC(ic, mode); | 1702 EmitCallIC(ic, mode); |
1701 // Restore context register. | 1703 // Restore context register. |
1702 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1704 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
1703 context()->Plug(r0); | 1705 context()->Plug(r0); |
1704 } | 1706 } |
1705 | 1707 |
1706 | 1708 |
1707 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 1709 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
1708 Expression* key, | 1710 Expression* key, |
1709 RelocInfo::Mode mode) { | 1711 RelocInfo::Mode mode) { |
1710 // Code common for calls using the IC. | 1712 // Code common for calls using the IC. |
1711 ZoneList<Expression*>* args = expr->arguments(); | 1713 ZoneList<Expression*>* args = expr->arguments(); |
1712 int arg_count = args->length(); | 1714 int arg_count = args->length(); |
1713 for (int i = 0; i < arg_count; i++) { | 1715 { PreserveStatementPositionScope scope(masm()->positions_recorder()); |
1714 VisitForStackValue(args->at(i)); | 1716 for (int i = 0; i < arg_count; i++) { |
| 1717 VisitForStackValue(args->at(i)); |
| 1718 } |
| 1719 VisitForAccumulatorValue(key); |
| 1720 __ mov(r2, r0); |
1715 } | 1721 } |
1716 VisitForAccumulatorValue(key); | |
1717 __ mov(r2, r0); | |
1718 // Record source position for debugger. | 1722 // Record source position for debugger. |
1719 SetSourcePosition(expr->position()); | 1723 SetSourcePosition(expr->position(), FORCED_POSITION); |
1720 // Call the IC initialization code. | 1724 // Call the IC initialization code. |
1721 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1725 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
1722 Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count, | 1726 Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count, |
1723 in_loop); | 1727 in_loop); |
1724 EmitCallIC(ic, mode); | 1728 EmitCallIC(ic, mode); |
1725 // Restore context register. | 1729 // Restore context register. |
1726 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1730 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
1727 context()->Plug(r0); | 1731 context()->Plug(r0); |
1728 } | 1732 } |
1729 | 1733 |
1730 | 1734 |
1731 void FullCodeGenerator::EmitCallWithStub(Call* expr) { | 1735 void FullCodeGenerator::EmitCallWithStub(Call* expr) { |
1732 // Code common for calls using the call stub. | 1736 // Code common for calls using the call stub. |
1733 ZoneList<Expression*>* args = expr->arguments(); | 1737 ZoneList<Expression*>* args = expr->arguments(); |
1734 int arg_count = args->length(); | 1738 int arg_count = args->length(); |
1735 for (int i = 0; i < arg_count; i++) { | 1739 { PreserveStatementPositionScope scope(masm()->positions_recorder()); |
1736 VisitForStackValue(args->at(i)); | 1740 for (int i = 0; i < arg_count; i++) { |
| 1741 VisitForStackValue(args->at(i)); |
| 1742 } |
1737 } | 1743 } |
1738 // Record source position for debugger. | 1744 // Record source position for debugger. |
1739 SetSourcePosition(expr->position()); | 1745 SetSourcePosition(expr->position(), FORCED_POSITION); |
1740 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1746 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
1741 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); | 1747 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); |
1742 __ CallStub(&stub); | 1748 __ CallStub(&stub); |
1743 // Restore context register. | 1749 // Restore context register. |
1744 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1750 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
1745 context()->DropAndPlug(1, r0); | 1751 context()->DropAndPlug(1, r0); |
1746 } | 1752 } |
1747 | 1753 |
1748 | 1754 |
1749 void FullCodeGenerator::VisitCall(Call* expr) { | 1755 void FullCodeGenerator::VisitCall(Call* expr) { |
1750 Comment cmnt(masm_, "[ Call"); | 1756 Comment cmnt(masm_, "[ Call"); |
1751 Expression* fun = expr->expression(); | 1757 Expression* fun = expr->expression(); |
1752 Variable* var = fun->AsVariableProxy()->AsVariable(); | 1758 Variable* var = fun->AsVariableProxy()->AsVariable(); |
1753 | 1759 |
1754 if (var != NULL && var->is_possibly_eval()) { | 1760 if (var != NULL && var->is_possibly_eval()) { |
1755 // In a call to eval, we first call %ResolvePossiblyDirectEval to | 1761 // In a call to eval, we first call %ResolvePossiblyDirectEval to |
1756 // resolve the function we need to call and the receiver of the | 1762 // resolve the function we need to call and the receiver of the |
1757 // call. Then we call the resolved function using the given | 1763 // call. Then we call the resolved function using the given |
1758 // arguments. | 1764 // arguments. |
1759 VisitForStackValue(fun); | |
1760 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | |
1761 __ push(r2); // Reserved receiver slot. | |
1762 | |
1763 // Push the arguments. | |
1764 ZoneList<Expression*>* args = expr->arguments(); | 1765 ZoneList<Expression*>* args = expr->arguments(); |
1765 int arg_count = args->length(); | 1766 int arg_count = args->length(); |
1766 for (int i = 0; i < arg_count; i++) { | 1767 |
1767 VisitForStackValue(args->at(i)); | 1768 { PreserveStatementPositionScope pos_scope(masm()->positions_recorder()); |
| 1769 |
| 1770 VisitForStackValue(fun); |
| 1771 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
| 1772 __ push(r2); // Reserved receiver slot. |
| 1773 |
| 1774 // Push the arguments. |
| 1775 for (int i = 0; i < arg_count; i++) { |
| 1776 VisitForStackValue(args->at(i)); |
| 1777 } |
| 1778 |
| 1779 // Push copy of the function - found below the arguments. |
| 1780 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 1781 __ push(r1); |
| 1782 |
| 1783 // Push copy of the first argument or undefined if it doesn't exist. |
| 1784 if (arg_count > 0) { |
| 1785 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); |
| 1786 __ push(r1); |
| 1787 } else { |
| 1788 __ push(r2); |
| 1789 } |
| 1790 |
| 1791 // Push the receiver of the enclosing function and do runtime call. |
| 1792 __ ldr(r1, |
| 1793 MemOperand(fp, (2 + scope()->num_parameters()) * kPointerSize)); |
| 1794 __ push(r1); |
| 1795 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3); |
| 1796 |
| 1797 // The runtime call returns a pair of values in r0 (function) and |
| 1798 // r1 (receiver). Touch up the stack with the right values. |
| 1799 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 1800 __ str(r1, MemOperand(sp, arg_count * kPointerSize)); |
1768 } | 1801 } |
1769 | 1802 |
1770 // Push copy of the function - found below the arguments. | |
1771 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | |
1772 __ push(r1); | |
1773 | |
1774 // Push copy of the first argument or undefined if it doesn't exist. | |
1775 if (arg_count > 0) { | |
1776 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); | |
1777 __ push(r1); | |
1778 } else { | |
1779 __ push(r2); | |
1780 } | |
1781 | |
1782 // Push the receiver of the enclosing function and do runtime call. | |
1783 __ ldr(r1, MemOperand(fp, (2 + scope()->num_parameters()) * kPointerSize)); | |
1784 __ push(r1); | |
1785 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3); | |
1786 | |
1787 // The runtime call returns a pair of values in r0 (function) and | |
1788 // r1 (receiver). Touch up the stack with the right values. | |
1789 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize)); | |
1790 __ str(r1, MemOperand(sp, arg_count * kPointerSize)); | |
1791 | |
1792 // Record source position for debugger. | 1803 // Record source position for debugger. |
1793 SetSourcePosition(expr->position()); | 1804 SetSourcePosition(expr->position(), FORCED_POSITION); |
1794 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1805 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
1795 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); | 1806 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); |
1796 __ CallStub(&stub); | 1807 __ CallStub(&stub); |
1797 // Restore context register. | 1808 // Restore context register. |
1798 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1809 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
1799 context()->DropAndPlug(1, r0); | 1810 context()->DropAndPlug(1, r0); |
1800 } else if (var != NULL && !var->is_this() && var->is_global()) { | 1811 } else if (var != NULL && !var->is_this() && var->is_global()) { |
1801 // Push global object as receiver for the call IC. | 1812 // Push global object as receiver for the call IC. |
1802 __ ldr(r0, CodeGenerator::GlobalObject()); | 1813 __ ldr(r0, CodeGenerator::GlobalObject()); |
1803 __ push(r0); | 1814 __ push(r0); |
1804 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); | 1815 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); |
1805 } else if (var != NULL && var->AsSlot() != NULL && | 1816 } else if (var != NULL && var->AsSlot() != NULL && |
1806 var->AsSlot()->type() == Slot::LOOKUP) { | 1817 var->AsSlot()->type() == Slot::LOOKUP) { |
1807 // Call to a lookup slot (dynamically introduced variable). | 1818 // Call to a lookup slot (dynamically introduced variable). |
1808 Label slow, done; | 1819 Label slow, done; |
1809 | 1820 |
1810 // Generate code for loading from variables potentially shadowed | 1821 { PreserveStatementPositionScope scope(masm()->positions_recorder()); |
1811 // by eval-introduced variables. | 1822 // Generate code for loading from variables potentially shadowed |
1812 EmitDynamicLoadFromSlotFastCase(var->AsSlot(), | 1823 // by eval-introduced variables. |
1813 NOT_INSIDE_TYPEOF, | 1824 EmitDynamicLoadFromSlotFastCase(var->AsSlot(), |
1814 &slow, | 1825 NOT_INSIDE_TYPEOF, |
1815 &done); | 1826 &slow, |
| 1827 &done); |
| 1828 } |
1816 | 1829 |
1817 __ bind(&slow); | 1830 __ bind(&slow); |
1818 // Call the runtime to find the function to call (returned in r0) | 1831 // Call the runtime to find the function to call (returned in r0) |
1819 // and the object holding it (returned in edx). | 1832 // and the object holding it (returned in edx). |
1820 __ push(context_register()); | 1833 __ push(context_register()); |
1821 __ mov(r2, Operand(var->name())); | 1834 __ mov(r2, Operand(var->name())); |
1822 __ push(r2); | 1835 __ push(r2); |
1823 __ CallRuntime(Runtime::kLoadContextSlot, 2); | 1836 __ CallRuntime(Runtime::kLoadContextSlot, 2); |
1824 __ Push(r0, r1); // Function, receiver. | 1837 __ Push(r0, r1); // Function, receiver. |
1825 | 1838 |
(...skipping 13 matching lines...) Expand all Loading... |
1839 __ bind(&call); | 1852 __ bind(&call); |
1840 } | 1853 } |
1841 | 1854 |
1842 EmitCallWithStub(expr); | 1855 EmitCallWithStub(expr); |
1843 } else if (fun->AsProperty() != NULL) { | 1856 } else if (fun->AsProperty() != NULL) { |
1844 // Call to an object property. | 1857 // Call to an object property. |
1845 Property* prop = fun->AsProperty(); | 1858 Property* prop = fun->AsProperty(); |
1846 Literal* key = prop->key()->AsLiteral(); | 1859 Literal* key = prop->key()->AsLiteral(); |
1847 if (key != NULL && key->handle()->IsSymbol()) { | 1860 if (key != NULL && key->handle()->IsSymbol()) { |
1848 // Call to a named property, use call IC. | 1861 // Call to a named property, use call IC. |
1849 VisitForStackValue(prop->obj()); | 1862 { PreserveStatementPositionScope scope(masm()->positions_recorder()); |
| 1863 VisitForStackValue(prop->obj()); |
| 1864 } |
1850 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); | 1865 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); |
1851 } else { | 1866 } else { |
1852 // Call to a keyed property. | 1867 // Call to a keyed property. |
1853 // For a synthetic property use keyed load IC followed by function call, | 1868 // For a synthetic property use keyed load IC followed by function call, |
1854 // for a regular property use keyed CallIC. | 1869 // for a regular property use keyed CallIC. |
1855 VisitForStackValue(prop->obj()); | 1870 { PreserveStatementPositionScope scope(masm()->positions_recorder()); |
| 1871 VisitForStackValue(prop->obj()); |
| 1872 } |
1856 if (prop->is_synthetic()) { | 1873 if (prop->is_synthetic()) { |
1857 VisitForAccumulatorValue(prop->key()); | 1874 { PreserveStatementPositionScope scope(masm()->positions_recorder()); |
| 1875 VisitForAccumulatorValue(prop->key()); |
| 1876 } |
1858 // Record source code position for IC call. | 1877 // Record source code position for IC call. |
1859 SetSourcePosition(prop->position()); | 1878 SetSourcePosition(prop->position(), FORCED_POSITION); |
1860 __ pop(r1); // We do not need to keep the receiver. | 1879 __ pop(r1); // We do not need to keep the receiver. |
1861 | 1880 |
1862 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1881 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
1863 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1882 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1864 __ ldr(r1, CodeGenerator::GlobalObject()); | 1883 __ ldr(r1, CodeGenerator::GlobalObject()); |
1865 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 1884 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
1866 __ Push(r0, r1); // Function, receiver. | 1885 __ Push(r0, r1); // Function, receiver. |
1867 EmitCallWithStub(expr); | 1886 EmitCallWithStub(expr); |
1868 } else { | 1887 } else { |
1869 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); | 1888 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); |
1870 } | 1889 } |
1871 } | 1890 } |
1872 } else { | 1891 } else { |
1873 // Call to some other expression. If the expression is an anonymous | 1892 // Call to some other expression. If the expression is an anonymous |
1874 // function literal not called in a loop, mark it as one that should | 1893 // function literal not called in a loop, mark it as one that should |
1875 // also use the fast code generator. | 1894 // also use the fast code generator. |
1876 FunctionLiteral* lit = fun->AsFunctionLiteral(); | 1895 FunctionLiteral* lit = fun->AsFunctionLiteral(); |
1877 if (lit != NULL && | 1896 if (lit != NULL && |
1878 lit->name()->Equals(Heap::empty_string()) && | 1897 lit->name()->Equals(Heap::empty_string()) && |
1879 loop_depth() == 0) { | 1898 loop_depth() == 0) { |
1880 lit->set_try_full_codegen(true); | 1899 lit->set_try_full_codegen(true); |
1881 } | 1900 } |
1882 VisitForStackValue(fun); | 1901 |
| 1902 { PreserveStatementPositionScope scope(masm()->positions_recorder()); |
| 1903 VisitForStackValue(fun); |
| 1904 } |
1883 // Load global receiver object. | 1905 // Load global receiver object. |
1884 __ ldr(r1, CodeGenerator::GlobalObject()); | 1906 __ ldr(r1, CodeGenerator::GlobalObject()); |
1885 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 1907 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
1886 __ push(r1); | 1908 __ push(r1); |
1887 // Emit function call. | 1909 // Emit function call. |
1888 EmitCallWithStub(expr); | 1910 EmitCallWithStub(expr); |
1889 } | 1911 } |
1890 } | 1912 } |
1891 | 1913 |
1892 | 1914 |
(...skipping 1508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3401 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 3423 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
3402 __ add(pc, r1, Operand(masm_->CodeObject())); | 3424 __ add(pc, r1, Operand(masm_->CodeObject())); |
3403 } | 3425 } |
3404 | 3426 |
3405 | 3427 |
3406 #undef __ | 3428 #undef __ |
3407 | 3429 |
3408 } } // namespace v8::internal | 3430 } } // namespace v8::internal |
3409 | 3431 |
3410 #endif // V8_TARGET_ARCH_ARM | 3432 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |