| 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_MIPS | 5 #if V8_TARGET_ARCH_MIPS |
| 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 1759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1770 __ lw(a1, MemOperand(a0)); // receiver | 1770 __ lw(a1, MemOperand(a0)); // receiver |
| 1771 __ Subu(a0, a0, Operand(kPointerSize)); | 1771 __ Subu(a0, a0, Operand(kPointerSize)); |
| 1772 __ Branch(&no_arg, lt, a0, Operand(sp)); | 1772 __ Branch(&no_arg, lt, a0, Operand(sp)); |
| 1773 __ lw(a2, MemOperand(a0)); // thisArg | 1773 __ lw(a2, MemOperand(a0)); // thisArg |
| 1774 __ Subu(a0, a0, Operand(kPointerSize)); | 1774 __ Subu(a0, a0, Operand(kPointerSize)); |
| 1775 __ Branch(&no_arg, lt, a0, Operand(sp)); | 1775 __ Branch(&no_arg, lt, a0, Operand(sp)); |
| 1776 __ lw(a3, MemOperand(a0)); // argArray | 1776 __ lw(a3, MemOperand(a0)); // argArray |
| 1777 __ bind(&no_arg); | 1777 __ bind(&no_arg); |
| 1778 __ Addu(sp, sp, Operand(scratch)); | 1778 __ Addu(sp, sp, Operand(scratch)); |
| 1779 __ sw(a2, MemOperand(sp)); | 1779 __ sw(a2, MemOperand(sp)); |
| 1780 __ mov(a0, a3); | 1780 __ mov(a2, a3); |
| 1781 } | 1781 } |
| 1782 | 1782 |
| 1783 // ----------- S t a t e ------------- | 1783 // ----------- S t a t e ------------- |
| 1784 // -- a0 : argArray | 1784 // -- a2 : argArray |
| 1785 // -- a1 : receiver | 1785 // -- a1 : receiver |
| 1786 // -- sp[0] : thisArg | 1786 // -- sp[0] : thisArg |
| 1787 // ----------------------------------- | 1787 // ----------------------------------- |
| 1788 | 1788 |
| 1789 // 2. Make sure the receiver is actually callable. | 1789 // 2. Make sure the receiver is actually callable. |
| 1790 Label receiver_not_callable; | 1790 Label receiver_not_callable; |
| 1791 __ JumpIfSmi(a1, &receiver_not_callable); | 1791 __ JumpIfSmi(a1, &receiver_not_callable); |
| 1792 __ lw(t0, FieldMemOperand(a1, HeapObject::kMapOffset)); | 1792 __ lw(t0, FieldMemOperand(a1, HeapObject::kMapOffset)); |
| 1793 __ lbu(t0, FieldMemOperand(t0, Map::kBitFieldOffset)); | 1793 __ lbu(t0, FieldMemOperand(t0, Map::kBitFieldOffset)); |
| 1794 __ And(t0, t0, Operand(1 << Map::kIsCallable)); | 1794 __ And(t0, t0, Operand(1 << Map::kIsCallable)); |
| 1795 __ Branch(&receiver_not_callable, eq, t0, Operand(zero_reg)); | 1795 __ Branch(&receiver_not_callable, eq, t0, Operand(zero_reg)); |
| 1796 | 1796 |
| 1797 // 3. Tail call with no arguments if argArray is null or undefined. | 1797 // 3. Tail call with no arguments if argArray is null or undefined. |
| 1798 Label no_arguments; | 1798 Label no_arguments; |
| 1799 __ JumpIfRoot(a0, Heap::kNullValueRootIndex, &no_arguments); | 1799 __ JumpIfRoot(a2, Heap::kNullValueRootIndex, &no_arguments); |
| 1800 __ JumpIfRoot(a0, Heap::kUndefinedValueRootIndex, &no_arguments); | 1800 __ JumpIfRoot(a2, Heap::kUndefinedValueRootIndex, &no_arguments); |
| 1801 | 1801 |
| 1802 // 4a. Apply the receiver to the given argArray (passing undefined for | 1802 // 4a. Apply the receiver to the given argArray. |
| 1803 // new.target). | 1803 __ Jump(masm->isolate()->builtins()->CallWithArrayLike(), |
| 1804 __ LoadRoot(a3, Heap::kUndefinedValueRootIndex); | 1804 RelocInfo::CODE_TARGET); |
| 1805 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); | |
| 1806 | 1805 |
| 1807 // 4b. The argArray is either null or undefined, so we tail call without any | 1806 // 4b. The argArray is either null or undefined, so we tail call without any |
| 1808 // arguments to the receiver. | 1807 // arguments to the receiver. |
| 1809 __ bind(&no_arguments); | 1808 __ bind(&no_arguments); |
| 1810 { | 1809 { |
| 1811 __ mov(a0, zero_reg); | 1810 __ mov(a0, zero_reg); |
| 1812 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 1811 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 1813 } | 1812 } |
| 1814 | 1813 |
| 1815 // 4c. The receiver is not callable, throw an appropriate TypeError. | 1814 // 4c. The receiver is not callable, throw an appropriate TypeError. |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1888 __ lw(a1, MemOperand(a0)); // target | 1887 __ lw(a1, MemOperand(a0)); // target |
| 1889 __ Subu(a0, a0, Operand(kPointerSize)); | 1888 __ Subu(a0, a0, Operand(kPointerSize)); |
| 1890 __ Branch(&no_arg, lt, a0, Operand(sp)); | 1889 __ Branch(&no_arg, lt, a0, Operand(sp)); |
| 1891 __ lw(a2, MemOperand(a0)); // thisArgument | 1890 __ lw(a2, MemOperand(a0)); // thisArgument |
| 1892 __ Subu(a0, a0, Operand(kPointerSize)); | 1891 __ Subu(a0, a0, Operand(kPointerSize)); |
| 1893 __ Branch(&no_arg, lt, a0, Operand(sp)); | 1892 __ Branch(&no_arg, lt, a0, Operand(sp)); |
| 1894 __ lw(a3, MemOperand(a0)); // argumentsList | 1893 __ lw(a3, MemOperand(a0)); // argumentsList |
| 1895 __ bind(&no_arg); | 1894 __ bind(&no_arg); |
| 1896 __ Addu(sp, sp, Operand(scratch)); | 1895 __ Addu(sp, sp, Operand(scratch)); |
| 1897 __ sw(a2, MemOperand(sp)); | 1896 __ sw(a2, MemOperand(sp)); |
| 1898 __ mov(a0, a3); | 1897 __ mov(a2, a3); |
| 1899 } | 1898 } |
| 1900 | 1899 |
| 1901 // ----------- S t a t e ------------- | 1900 // ----------- S t a t e ------------- |
| 1902 // -- a0 : argumentsList | 1901 // -- a2 : argumentsList |
| 1903 // -- a1 : target | 1902 // -- a1 : target |
| 1904 // -- sp[0] : thisArgument | 1903 // -- sp[0] : thisArgument |
| 1905 // ----------------------------------- | 1904 // ----------------------------------- |
| 1906 | 1905 |
| 1907 // 2. Make sure the target is actually callable. | 1906 // 2. Make sure the target is actually callable. |
| 1908 Label target_not_callable; | 1907 Label target_not_callable; |
| 1909 __ JumpIfSmi(a1, &target_not_callable); | 1908 __ JumpIfSmi(a1, &target_not_callable); |
| 1910 __ lw(t0, FieldMemOperand(a1, HeapObject::kMapOffset)); | 1909 __ lw(t0, FieldMemOperand(a1, HeapObject::kMapOffset)); |
| 1911 __ lbu(t0, FieldMemOperand(t0, Map::kBitFieldOffset)); | 1910 __ lbu(t0, FieldMemOperand(t0, Map::kBitFieldOffset)); |
| 1912 __ And(t0, t0, Operand(1 << Map::kIsCallable)); | 1911 __ And(t0, t0, Operand(1 << Map::kIsCallable)); |
| 1913 __ Branch(&target_not_callable, eq, t0, Operand(zero_reg)); | 1912 __ Branch(&target_not_callable, eq, t0, Operand(zero_reg)); |
| 1914 | 1913 |
| 1915 // 3a. Apply the target to the given argumentsList (passing undefined for | 1914 // 3a. Apply the target to the given argumentsList. |
| 1916 // new.target). | 1915 __ Jump(masm->isolate()->builtins()->CallWithArrayLike(), |
| 1917 __ LoadRoot(a3, Heap::kUndefinedValueRootIndex); | 1916 RelocInfo::CODE_TARGET); |
| 1918 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); | |
| 1919 | 1917 |
| 1920 // 3b. The target is not callable, throw an appropriate TypeError. | 1918 // 3b. The target is not callable, throw an appropriate TypeError. |
| 1921 __ bind(&target_not_callable); | 1919 __ bind(&target_not_callable); |
| 1922 { | 1920 { |
| 1923 __ sw(a1, MemOperand(sp)); | 1921 __ sw(a1, MemOperand(sp)); |
| 1924 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); | 1922 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); |
| 1925 } | 1923 } |
| 1926 } | 1924 } |
| 1927 | 1925 |
| 1928 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { | 1926 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1952 __ lw(a1, MemOperand(a0)); // target | 1950 __ lw(a1, MemOperand(a0)); // target |
| 1953 __ mov(a3, a1); // new.target defaults to target | 1951 __ mov(a3, a1); // new.target defaults to target |
| 1954 __ Subu(a0, a0, Operand(kPointerSize)); | 1952 __ Subu(a0, a0, Operand(kPointerSize)); |
| 1955 __ Branch(&no_arg, lt, a0, Operand(sp)); | 1953 __ Branch(&no_arg, lt, a0, Operand(sp)); |
| 1956 __ lw(a2, MemOperand(a0)); // argumentsList | 1954 __ lw(a2, MemOperand(a0)); // argumentsList |
| 1957 __ Subu(a0, a0, Operand(kPointerSize)); | 1955 __ Subu(a0, a0, Operand(kPointerSize)); |
| 1958 __ Branch(&no_arg, lt, a0, Operand(sp)); | 1956 __ Branch(&no_arg, lt, a0, Operand(sp)); |
| 1959 __ lw(a3, MemOperand(a0)); // new.target | 1957 __ lw(a3, MemOperand(a0)); // new.target |
| 1960 __ bind(&no_arg); | 1958 __ bind(&no_arg); |
| 1961 __ Addu(sp, sp, Operand(scratch)); | 1959 __ Addu(sp, sp, Operand(scratch)); |
| 1962 __ mov(a0, a2); | |
| 1963 } | 1960 } |
| 1964 | 1961 |
| 1965 // ----------- S t a t e ------------- | 1962 // ----------- S t a t e ------------- |
| 1966 // -- a0 : argumentsList | 1963 // -- a2 : argumentsList |
| 1967 // -- a3 : new.target | 1964 // -- a3 : new.target |
| 1968 // -- a1 : target | 1965 // -- a1 : target |
| 1969 // -- sp[0] : receiver (undefined) | 1966 // -- sp[0] : receiver (undefined) |
| 1970 // ----------------------------------- | 1967 // ----------------------------------- |
| 1971 | 1968 |
| 1972 // 2. Make sure the target is actually a constructor. | 1969 // 2. Make sure the target is actually a constructor. |
| 1973 Label target_not_constructor; | 1970 Label target_not_constructor; |
| 1974 __ JumpIfSmi(a1, &target_not_constructor); | 1971 __ JumpIfSmi(a1, &target_not_constructor); |
| 1975 __ lw(t0, FieldMemOperand(a1, HeapObject::kMapOffset)); | 1972 __ lw(t0, FieldMemOperand(a1, HeapObject::kMapOffset)); |
| 1976 __ lbu(t0, FieldMemOperand(t0, Map::kBitFieldOffset)); | 1973 __ lbu(t0, FieldMemOperand(t0, Map::kBitFieldOffset)); |
| 1977 __ And(t0, t0, Operand(1 << Map::kIsConstructor)); | 1974 __ And(t0, t0, Operand(1 << Map::kIsConstructor)); |
| 1978 __ Branch(&target_not_constructor, eq, t0, Operand(zero_reg)); | 1975 __ Branch(&target_not_constructor, eq, t0, Operand(zero_reg)); |
| 1979 | 1976 |
| 1980 // 3. Make sure the target is actually a constructor. | 1977 // 3. Make sure the target is actually a constructor. |
| 1981 Label new_target_not_constructor; | 1978 Label new_target_not_constructor; |
| 1982 __ JumpIfSmi(a3, &new_target_not_constructor); | 1979 __ JumpIfSmi(a3, &new_target_not_constructor); |
| 1983 __ lw(t0, FieldMemOperand(a3, HeapObject::kMapOffset)); | 1980 __ lw(t0, FieldMemOperand(a3, HeapObject::kMapOffset)); |
| 1984 __ lbu(t0, FieldMemOperand(t0, Map::kBitFieldOffset)); | 1981 __ lbu(t0, FieldMemOperand(t0, Map::kBitFieldOffset)); |
| 1985 __ And(t0, t0, Operand(1 << Map::kIsConstructor)); | 1982 __ And(t0, t0, Operand(1 << Map::kIsConstructor)); |
| 1986 __ Branch(&new_target_not_constructor, eq, t0, Operand(zero_reg)); | 1983 __ Branch(&new_target_not_constructor, eq, t0, Operand(zero_reg)); |
| 1987 | 1984 |
| 1988 // 4a. Construct the target with the given new.target and argumentsList. | 1985 // 4a. Construct the target with the given new.target and argumentsList. |
| 1989 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); | 1986 __ Jump(masm->isolate()->builtins()->ConstructWithArrayLike(), |
| 1987 RelocInfo::CODE_TARGET); |
| 1990 | 1988 |
| 1991 // 4b. The target is not a constructor, throw an appropriate TypeError. | 1989 // 4b. The target is not a constructor, throw an appropriate TypeError. |
| 1992 __ bind(&target_not_constructor); | 1990 __ bind(&target_not_constructor); |
| 1993 { | 1991 { |
| 1994 __ sw(a1, MemOperand(sp)); | 1992 __ sw(a1, MemOperand(sp)); |
| 1995 __ TailCallRuntime(Runtime::kThrowNotConstructor); | 1993 __ TailCallRuntime(Runtime::kThrowNotConstructor); |
| 1996 } | 1994 } |
| 1997 | 1995 |
| 1998 // 4c. The new.target is not a constructor, throw an appropriate TypeError. | 1996 // 4c. The new.target is not a constructor, throw an appropriate TypeError. |
| 1999 __ bind(&new_target_not_constructor); | 1997 __ bind(&new_target_not_constructor); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2020 __ lw(a1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + | 2018 __ lw(a1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + |
| 2021 kPointerSize))); | 2019 kPointerSize))); |
| 2022 __ mov(sp, fp); | 2020 __ mov(sp, fp); |
| 2023 __ MultiPop(fp.bit() | ra.bit()); | 2021 __ MultiPop(fp.bit() | ra.bit()); |
| 2024 __ Lsa(sp, sp, a1, kPointerSizeLog2 - kSmiTagSize); | 2022 __ Lsa(sp, sp, a1, kPointerSizeLog2 - kSmiTagSize); |
| 2025 // Adjust for the receiver. | 2023 // Adjust for the receiver. |
| 2026 __ Addu(sp, sp, Operand(kPointerSize)); | 2024 __ Addu(sp, sp, Operand(kPointerSize)); |
| 2027 } | 2025 } |
| 2028 | 2026 |
| 2029 // static | 2027 // static |
| 2030 void Builtins::Generate_Apply(MacroAssembler* masm) { | 2028 void Builtins::Generate_Varargs(MacroAssembler* masm, Handle<Code> code) { |
| 2031 // ----------- S t a t e ------------- | 2029 // ----------- S t a t e ------------- |
| 2032 // -- a0 : argumentsList | 2030 // -- a1 : target |
| 2033 // -- a1 : target | 2031 // -- a0 : number of parameters on the stack (not including the receiver) |
| 2034 // -- a3 : new.target (checked to be constructor or undefined) | 2032 // -- a2 : arguments list (a FixedArray) |
| 2035 // -- sp[0] : thisArgument | 2033 // -- t0 : len (number of elements to push from args) |
| 2034 // -- a3 : new.target (for [[Construct]]) |
| 2036 // ----------------------------------- | 2035 // ----------------------------------- |
| 2037 | 2036 __ AssertFixedArray(a2); |
| 2038 // Create the list of arguments from the array-like argumentsList. | |
| 2039 { | |
| 2040 Label create_arguments, create_array, create_holey_array, create_runtime, | |
| 2041 done_create; | |
| 2042 __ JumpIfSmi(a0, &create_runtime); | |
| 2043 | |
| 2044 // Load the map of argumentsList into a2. | |
| 2045 __ lw(a2, FieldMemOperand(a0, HeapObject::kMapOffset)); | |
| 2046 | |
| 2047 // Load native context into t0. | |
| 2048 __ lw(t0, NativeContextMemOperand()); | |
| 2049 | |
| 2050 // Check if argumentsList is an (unmodified) arguments object. | |
| 2051 __ lw(at, ContextMemOperand(t0, Context::SLOPPY_ARGUMENTS_MAP_INDEX)); | |
| 2052 __ Branch(&create_arguments, eq, a2, Operand(at)); | |
| 2053 __ lw(at, ContextMemOperand(t0, Context::STRICT_ARGUMENTS_MAP_INDEX)); | |
| 2054 __ Branch(&create_arguments, eq, a2, Operand(at)); | |
| 2055 | |
| 2056 // Check if argumentsList is a fast JSArray. | |
| 2057 __ lbu(v0, FieldMemOperand(a2, Map::kInstanceTypeOffset)); | |
| 2058 __ Branch(&create_array, eq, v0, Operand(JS_ARRAY_TYPE)); | |
| 2059 | |
| 2060 // Ask the runtime to create the list (actually a FixedArray). | |
| 2061 __ bind(&create_runtime); | |
| 2062 { | |
| 2063 FrameScope scope(masm, StackFrame::INTERNAL); | |
| 2064 __ Push(a1, a3, a0); | |
| 2065 __ CallRuntime(Runtime::kCreateListFromArrayLike); | |
| 2066 __ mov(a0, v0); | |
| 2067 __ Pop(a1, a3); | |
| 2068 __ lw(a2, FieldMemOperand(v0, FixedArray::kLengthOffset)); | |
| 2069 __ SmiUntag(a2); | |
| 2070 } | |
| 2071 __ Branch(&done_create); | |
| 2072 | |
| 2073 // Try to create the list from an arguments object. | |
| 2074 __ bind(&create_arguments); | |
| 2075 __ lw(a2, FieldMemOperand(a0, JSArgumentsObject::kLengthOffset)); | |
| 2076 __ lw(t0, FieldMemOperand(a0, JSObject::kElementsOffset)); | |
| 2077 __ lw(at, FieldMemOperand(t0, FixedArray::kLengthOffset)); | |
| 2078 __ Branch(&create_runtime, ne, a2, Operand(at)); | |
| 2079 __ SmiUntag(a2); | |
| 2080 __ mov(a0, t0); | |
| 2081 __ Branch(&done_create); | |
| 2082 | |
| 2083 // For holey JSArrays we need to check that the array prototype chain | |
| 2084 // protector is intact and our prototype is the Array.prototype actually. | |
| 2085 __ bind(&create_holey_array); | |
| 2086 __ lw(a2, FieldMemOperand(a2, Map::kPrototypeOffset)); | |
| 2087 __ lw(at, ContextMemOperand(t0, Context::INITIAL_ARRAY_PROTOTYPE_INDEX)); | |
| 2088 __ Branch(&create_runtime, ne, a2, Operand(at)); | |
| 2089 __ LoadRoot(at, Heap::kArrayProtectorRootIndex); | |
| 2090 __ lw(a2, FieldMemOperand(at, PropertyCell::kValueOffset)); | |
| 2091 __ Branch(&create_runtime, ne, a2, | |
| 2092 Operand(Smi::FromInt(Isolate::kProtectorValid))); | |
| 2093 __ lw(a2, FieldMemOperand(a0, JSArray::kLengthOffset)); | |
| 2094 __ lw(a0, FieldMemOperand(a0, JSArray::kElementsOffset)); | |
| 2095 __ SmiUntag(a2); | |
| 2096 __ Branch(&done_create); | |
| 2097 | |
| 2098 // Try to create the list from a JSArray object. | |
| 2099 __ bind(&create_array); | |
| 2100 __ lbu(t1, FieldMemOperand(a2, Map::kBitField2Offset)); | |
| 2101 __ DecodeField<Map::ElementsKindBits>(t1); | |
| 2102 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | |
| 2103 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | |
| 2104 STATIC_ASSERT(FAST_ELEMENTS == 2); | |
| 2105 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); | |
| 2106 __ Branch(&create_holey_array, eq, t1, Operand(FAST_HOLEY_SMI_ELEMENTS)); | |
| 2107 __ Branch(&create_holey_array, eq, t1, Operand(FAST_HOLEY_ELEMENTS)); | |
| 2108 __ Branch(&create_runtime, hi, t1, Operand(FAST_ELEMENTS)); | |
| 2109 __ lw(a2, FieldMemOperand(a0, JSArray::kLengthOffset)); | |
| 2110 __ lw(a0, FieldMemOperand(a0, JSArray::kElementsOffset)); | |
| 2111 __ SmiUntag(a2); | |
| 2112 | |
| 2113 __ bind(&done_create); | |
| 2114 } | |
| 2115 | 2037 |
| 2116 // Check for stack overflow. | 2038 // Check for stack overflow. |
| 2117 { | 2039 { |
| 2118 // Check the stack for overflow. We are not trying to catch interruptions | 2040 // Check the stack for overflow. We are not trying to catch interruptions |
| 2119 // (i.e. debug break and preemption) here, so check the "real stack limit". | 2041 // (i.e. debug break and preemption) here, so check the "real stack limit". |
| 2120 Label done; | 2042 Label done; |
| 2121 __ LoadRoot(t0, Heap::kRealStackLimitRootIndex); | 2043 __ LoadRoot(t1, Heap::kRealStackLimitRootIndex); |
| 2122 // Make ip the space we have left. The stack might already be overflowed | 2044 // Make ip the space we have left. The stack might already be overflowed |
| 2123 // here which will cause ip to become negative. | 2045 // here which will cause ip to become negative. |
| 2124 __ Subu(t0, sp, t0); | 2046 __ Subu(t1, sp, t1); |
| 2125 // Check if the arguments will overflow the stack. | 2047 // Check if the arguments will overflow the stack. |
| 2126 __ sll(at, a2, kPointerSizeLog2); | 2048 __ sll(at, t0, kPointerSizeLog2); |
| 2127 __ Branch(&done, gt, t0, Operand(at)); // Signed comparison. | 2049 __ Branch(&done, gt, t1, Operand(at)); // Signed comparison. |
| 2128 __ TailCallRuntime(Runtime::kThrowStackOverflow); | 2050 __ TailCallRuntime(Runtime::kThrowStackOverflow); |
| 2129 __ bind(&done); | 2051 __ bind(&done); |
| 2130 } | 2052 } |
| 2131 | 2053 |
| 2132 // ----------- S t a t e ------------- | |
| 2133 // -- a1 : target | |
| 2134 // -- a0 : args (a FixedArray built from argumentsList) | |
| 2135 // -- a2 : len (number of elements to push from args) | |
| 2136 // -- a3 : new.target (checked to be constructor or undefined) | |
| 2137 // -- sp[0] : thisArgument | |
| 2138 // ----------------------------------- | |
| 2139 | |
| 2140 // Push arguments onto the stack (thisArgument is already on the stack). | 2054 // Push arguments onto the stack (thisArgument is already on the stack). |
| 2141 { | 2055 { |
| 2142 __ mov(t0, zero_reg); | 2056 __ mov(t2, zero_reg); |
| 2143 Label done, push, loop; | 2057 Label done, push, loop; |
| 2144 __ LoadRoot(t1, Heap::kTheHoleValueRootIndex); | 2058 __ LoadRoot(t1, Heap::kTheHoleValueRootIndex); |
| 2145 __ bind(&loop); | 2059 __ bind(&loop); |
| 2146 __ Branch(&done, eq, t0, Operand(a2)); | 2060 __ Branch(&done, eq, t2, Operand(t0)); |
| 2147 __ Lsa(at, a0, t0, kPointerSizeLog2); | 2061 __ Lsa(at, a2, t2, kPointerSizeLog2); |
| 2148 __ lw(at, FieldMemOperand(at, FixedArray::kHeaderSize)); | 2062 __ lw(at, FieldMemOperand(at, FixedArray::kHeaderSize)); |
| 2149 __ Branch(&push, ne, t1, Operand(at)); | 2063 __ Branch(&push, ne, t1, Operand(at)); |
| 2150 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 2064 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 2151 __ bind(&push); | 2065 __ bind(&push); |
| 2152 __ Push(at); | 2066 __ Push(at); |
| 2153 __ Addu(t0, t0, Operand(1)); | 2067 __ Addu(t2, t2, Operand(1)); |
| 2154 __ Branch(&loop); | 2068 __ Branch(&loop); |
| 2155 __ bind(&done); | 2069 __ bind(&done); |
| 2156 __ Move(a0, t0); | 2070 __ Addu(a0, a0, t2); |
| 2157 } | 2071 } |
| 2158 | 2072 |
| 2159 // Dispatch to Call or Construct depending on whether new.target is undefined. | 2073 // Tail-call to the actual Call or Construct builtin. |
| 2160 { | 2074 __ Jump(code, RelocInfo::CODE_TARGET); |
| 2161 Label construct; | |
| 2162 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | |
| 2163 __ Branch(&construct, ne, a3, Operand(at)); | |
| 2164 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | |
| 2165 __ bind(&construct); | |
| 2166 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | |
| 2167 } | |
| 2168 } | 2075 } |
| 2169 | 2076 |
| 2170 // static | 2077 // static |
| 2171 void Builtins::Generate_ForwardVarargs(MacroAssembler* masm, | 2078 void Builtins::Generate_ForwardVarargs(MacroAssembler* masm, |
| 2172 Handle<Code> code) { | 2079 Handle<Code> code) { |
| 2173 // ----------- S t a t e ------------- | 2080 // ----------- S t a t e ------------- |
| 2174 // -- a0 : the number of arguments (not including the receiver) | 2081 // -- a0 : the number of arguments (not including the receiver) |
| 2175 // -- a3 : the new.target (for [[Construct]] calls) | 2082 // -- a3 : the new.target (for [[Construct]] calls) |
| 2176 // -- a1 : the target to call (can be any Object) | 2083 // -- a1 : the target to call (can be any Object) |
| 2177 // -- a2 : start index (to support rest parameters) | 2084 // -- a2 : start index (to support rest parameters) |
| (...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3112 // Now jump to the instructions of the returned code object. | 3019 // Now jump to the instructions of the returned code object. |
| 3113 __ Jump(at, v0, Code::kHeaderSize - kHeapObjectTag); | 3020 __ Jump(at, v0, Code::kHeaderSize - kHeapObjectTag); |
| 3114 } | 3021 } |
| 3115 | 3022 |
| 3116 #undef __ | 3023 #undef __ |
| 3117 | 3024 |
| 3118 } // namespace internal | 3025 } // namespace internal |
| 3119 } // namespace v8 | 3026 } // namespace v8 |
| 3120 | 3027 |
| 3121 #endif // V8_TARGET_ARCH_MIPS | 3028 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |