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_X87 | 5 #if V8_TARGET_ARCH_X87 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.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 1779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1790 __ bind(&stack_overflow); | 1790 __ bind(&stack_overflow); |
1791 { | 1791 { |
1792 FrameScope frame(masm, StackFrame::MANUAL); | 1792 FrameScope frame(masm, StackFrame::MANUAL); |
1793 EnterArgumentsAdaptorFrame(masm); | 1793 EnterArgumentsAdaptorFrame(masm); |
1794 __ CallRuntime(Runtime::kThrowStackOverflow, 0); | 1794 __ CallRuntime(Runtime::kThrowStackOverflow, 0); |
1795 __ int3(); | 1795 __ int3(); |
1796 } | 1796 } |
1797 } | 1797 } |
1798 | 1798 |
1799 | 1799 |
| 1800 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver, |
| 1801 Register function_template_info, |
| 1802 Register scratch0, Register scratch1, |
| 1803 Label* receiver_check_failed) { |
| 1804 // If receiver is not an object, jump to receiver_check_failed. |
| 1805 __ CmpObjectType(receiver, FIRST_JS_OBJECT_TYPE, scratch0); |
| 1806 __ j(below, receiver_check_failed); |
| 1807 |
| 1808 // If there is no signature, return the holder. |
| 1809 __ CompareRoot(FieldOperand(function_template_info, |
| 1810 FunctionTemplateInfo::kSignatureOffset), |
| 1811 Heap::kUndefinedValueRootIndex); |
| 1812 Label receiver_check_passed; |
| 1813 __ j(equal, &receiver_check_passed, Label::kNear); |
| 1814 |
| 1815 // Walk the prototype chain. |
| 1816 Label prototype_loop_start; |
| 1817 __ bind(&prototype_loop_start); |
| 1818 |
| 1819 // End if receiver is null or if it's a hidden prototype. |
| 1820 __ CompareRoot(receiver, Heap::kNullValueRootIndex); |
| 1821 __ j(equal, receiver_check_failed, Label::kNear); |
| 1822 __ mov(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); |
| 1823 __ test(FieldOperand(scratch0, Map::kBitField3Offset), |
| 1824 Immediate(Map::IsHiddenPrototype::kMask)); |
| 1825 __ j(not_zero, receiver_check_failed, Label::kNear); |
| 1826 |
| 1827 // Get the constructor, if any. |
| 1828 __ GetMapConstructor(scratch0, scratch0, scratch1); |
| 1829 __ CmpInstanceType(scratch1, JS_FUNCTION_TYPE); |
| 1830 Label next_prototype; |
| 1831 __ j(not_equal, &next_prototype, Label::kNear); |
| 1832 |
| 1833 // Get the constructor's signature. |
| 1834 __ mov(scratch0, |
| 1835 FieldOperand(scratch0, JSFunction::kSharedFunctionInfoOffset)); |
| 1836 __ mov(scratch0, |
| 1837 FieldOperand(scratch0, SharedFunctionInfo::kFunctionDataOffset)); |
| 1838 |
| 1839 // Loop through the chain of inheriting function templates. |
| 1840 Label function_template_loop; |
| 1841 __ bind(&function_template_loop); |
| 1842 |
| 1843 // If the signatures match, we have a compatible receiver. |
| 1844 __ cmp(scratch0, FieldOperand(function_template_info, |
| 1845 FunctionTemplateInfo::kSignatureOffset)); |
| 1846 __ j(equal, &receiver_check_passed, Label::kNear); |
| 1847 |
| 1848 // If the current type is not a FunctionTemplateInfo, load the next prototype |
| 1849 // in the chain. |
| 1850 __ JumpIfSmi(scratch0, &next_prototype, Label::kNear); |
| 1851 __ CmpObjectType(scratch0, FUNCTION_TEMPLATE_INFO_TYPE, scratch1); |
| 1852 __ j(not_equal, &next_prototype, Label::kNear); |
| 1853 |
| 1854 // Otherwise load the parent function template and iterate. |
| 1855 __ mov(scratch0, |
| 1856 FieldOperand(scratch0, FunctionTemplateInfo::kParentTemplateOffset)); |
| 1857 __ jmp(&function_template_loop, Label::kNear); |
| 1858 |
| 1859 // Load the next prototype and iterate. |
| 1860 __ bind(&next_prototype); |
| 1861 __ mov(receiver, FieldOperand(receiver, HeapObject::kMapOffset)); |
| 1862 __ mov(receiver, FieldOperand(receiver, Map::kPrototypeOffset)); |
| 1863 __ jmp(&prototype_loop_start, Label::kNear); |
| 1864 |
| 1865 __ bind(&receiver_check_passed); |
| 1866 } |
| 1867 |
| 1868 |
| 1869 void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) { |
| 1870 // ----------- S t a t e ------------- |
| 1871 // -- eax : number of arguments (not including the receiver) |
| 1872 // -- edi : callee |
| 1873 // -- esi : context |
| 1874 // -- esp[0] : return address |
| 1875 // -- esp[4] : last argument |
| 1876 // -- ... |
| 1877 // -- esp[eax * 4] : first argument |
| 1878 // -- esp[(eax + 1) * 4] : receiver |
| 1879 // ----------------------------------- |
| 1880 |
| 1881 // Load the receiver. |
| 1882 Operand receiver_operand(esp, eax, times_pointer_size, kPCOnStackSize); |
| 1883 __ mov(ecx, receiver_operand); |
| 1884 |
| 1885 // Update the receiver if this is a contextual call. |
| 1886 Label set_global_proxy, valid_receiver; |
| 1887 __ CompareRoot(ecx, Heap::kUndefinedValueRootIndex); |
| 1888 __ j(equal, &set_global_proxy); |
| 1889 __ bind(&valid_receiver); |
| 1890 |
| 1891 // Load the FunctionTemplateInfo. |
| 1892 __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 1893 __ mov(ebx, FieldOperand(ebx, SharedFunctionInfo::kFunctionDataOffset)); |
| 1894 |
| 1895 // Do the compatible receiver check. |
| 1896 Label receiver_check_failed; |
| 1897 __ Push(eax); |
| 1898 CompatibleReceiverCheck(masm, ecx, ebx, edx, eax, &receiver_check_failed); |
| 1899 __ Pop(eax); |
| 1900 // Get the callback offset from the FunctionTemplateInfo, and jump to the |
| 1901 // beginning of the code. |
| 1902 __ mov(edx, FieldOperand(ebx, FunctionTemplateInfo::kCallCodeOffset)); |
| 1903 __ mov(edx, FieldOperand(edx, CallHandlerInfo::kFastHandlerOffset)); |
| 1904 __ add(edx, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
| 1905 __ jmp(edx); |
| 1906 |
| 1907 __ bind(&set_global_proxy); |
| 1908 __ mov(ecx, GlobalObjectOperand()); |
| 1909 __ mov(ecx, FieldOperand(ecx, JSGlobalObject::kGlobalProxyOffset)); |
| 1910 __ mov(receiver_operand, ecx); |
| 1911 __ jmp(&valid_receiver, Label::kNear); |
| 1912 |
| 1913 // Compatible receiver check failed: pop return address, arguments and |
| 1914 // receiver and throw an Illegal Invocation exception. |
| 1915 __ bind(&receiver_check_failed); |
| 1916 __ Pop(eax); |
| 1917 __ PopReturnAddressTo(ebx); |
| 1918 __ lea(eax, Operand(eax, times_pointer_size, 1 * kPointerSize)); |
| 1919 __ add(esp, eax); |
| 1920 __ PushReturnAddressFrom(ebx); |
| 1921 { |
| 1922 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1923 __ TailCallRuntime(Runtime::kThrowIllegalInvocation, 0, 1); |
| 1924 } |
| 1925 } |
| 1926 |
| 1927 |
1800 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { | 1928 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { |
1801 // Lookup the function in the JavaScript frame. | 1929 // Lookup the function in the JavaScript frame. |
1802 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1930 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
1803 { | 1931 { |
1804 FrameScope scope(masm, StackFrame::INTERNAL); | 1932 FrameScope scope(masm, StackFrame::INTERNAL); |
1805 // Pass function as argument. | 1933 // Pass function as argument. |
1806 __ push(eax); | 1934 __ push(eax); |
1807 __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1); | 1935 __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1); |
1808 } | 1936 } |
1809 | 1937 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1850 | 1978 |
1851 __ bind(&ok); | 1979 __ bind(&ok); |
1852 __ ret(0); | 1980 __ ret(0); |
1853 } | 1981 } |
1854 | 1982 |
1855 #undef __ | 1983 #undef __ |
1856 } // namespace internal | 1984 } // namespace internal |
1857 } // namespace v8 | 1985 } // namespace v8 |
1858 | 1986 |
1859 #endif // V8_TARGET_ARCH_X87 | 1987 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |