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 1908 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1919 __ bind(&class_constructor); | 1919 __ bind(&class_constructor); |
1920 { | 1920 { |
1921 FrameScope frame(masm, StackFrame::INTERNAL); | 1921 FrameScope frame(masm, StackFrame::INTERNAL); |
1922 __ Push(a1); | 1922 __ Push(a1); |
1923 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 1); | 1923 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 1); |
1924 } | 1924 } |
1925 } | 1925 } |
1926 | 1926 |
1927 | 1927 |
1928 // static | 1928 // static |
| 1929 void Builtins::Generate_CallBoundFunction(MacroAssembler* masm) { |
| 1930 // ----------- S t a t e ------------- |
| 1931 // -- a0 : the number of arguments (not including the receiver) |
| 1932 // -- a1 : the function to call (checked to be a JSBoundFunction) |
| 1933 // ----------------------------------- |
| 1934 __ AssertBoundFunction(a1); |
| 1935 |
| 1936 // Patch the receiver to [[BoundThis]]. |
| 1937 { |
| 1938 __ lw(at, FieldMemOperand(a1, JSBoundFunction::kBoundThisOffset)); |
| 1939 __ sll(t0, a0, kPointerSizeLog2); |
| 1940 __ addu(t0, t0, sp); |
| 1941 __ sw(at, MemOperand(t0)); |
| 1942 } |
| 1943 |
| 1944 // Load [[BoundArguments]] into a2 and length of that into t0. |
| 1945 __ lw(a2, FieldMemOperand(a1, JSBoundFunction::kBoundArgumentsOffset)); |
| 1946 __ lw(t0, FieldMemOperand(a2, FixedArray::kLengthOffset)); |
| 1947 __ SmiUntag(t0); |
| 1948 |
| 1949 // ----------- S t a t e ------------- |
| 1950 // -- a0 : the number of arguments (not including the receiver) |
| 1951 // -- a1 : the function to call (checked to be a JSBoundFunction) |
| 1952 // -- a2 : the [[BoundArguments]] (implemented as FixedArray) |
| 1953 // -- t0 : the number of [[BoundArguments]] |
| 1954 // ----------------------------------- |
| 1955 |
| 1956 // Reserve stack space for the [[BoundArguments]]. |
| 1957 { |
| 1958 Label done; |
| 1959 __ sll(t1, t0, kPointerSizeLog2); |
| 1960 __ Subu(sp, sp, Operand(t1)); |
| 1961 // Check the stack for overflow. We are not trying to catch interruptions |
| 1962 // (i.e. debug break and preemption) here, so check the "real stack limit". |
| 1963 __ LoadRoot(at, Heap::kRealStackLimitRootIndex); |
| 1964 __ Branch(&done, gt, sp, Operand(at)); // Signed comparison. |
| 1965 // Restore the stack pointer. |
| 1966 __ Addu(sp, sp, Operand(t1)); |
| 1967 { |
| 1968 FrameScope scope(masm, StackFrame::MANUAL); |
| 1969 __ EnterFrame(StackFrame::INTERNAL); |
| 1970 __ CallRuntime(Runtime::kThrowStackOverflow, 0); |
| 1971 } |
| 1972 __ bind(&done); |
| 1973 } |
| 1974 |
| 1975 // Relocate arguments down the stack. |
| 1976 { |
| 1977 Label loop, done_loop; |
| 1978 __ mov(t1, zero_reg); |
| 1979 __ bind(&loop); |
| 1980 __ Branch(&done_loop, gt, t1, Operand(a0)); |
| 1981 __ sll(t2, t0, kPointerSizeLog2); |
| 1982 __ addu(t2, t2, sp); |
| 1983 __ lw(at, MemOperand(t2)); |
| 1984 __ sll(t2, t1, kPointerSizeLog2); |
| 1985 __ addu(t2, t2, sp); |
| 1986 __ sw(at, MemOperand(t2)); |
| 1987 __ Addu(t0, t0, Operand(1)); |
| 1988 __ Addu(t1, t1, Operand(1)); |
| 1989 __ Branch(&loop); |
| 1990 __ bind(&done_loop); |
| 1991 } |
| 1992 |
| 1993 // Copy [[BoundArguments]] to the stack (below the arguments). |
| 1994 { |
| 1995 Label loop, done_loop; |
| 1996 __ lw(t0, FieldMemOperand(a2, FixedArray::kLengthOffset)); |
| 1997 __ SmiUntag(t0); |
| 1998 __ Addu(a2, a2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 1999 __ bind(&loop); |
| 2000 __ Subu(t0, t0, Operand(1)); |
| 2001 __ Branch(&done_loop, lt, t0, Operand(zero_reg)); |
| 2002 __ sll(t1, t0, kPointerSizeLog2); |
| 2003 __ addu(t1, t1, a2); |
| 2004 __ lw(at, MemOperand(t1)); |
| 2005 __ sll(t1, a0, kPointerSizeLog2); |
| 2006 __ addu(t1, t1, sp); |
| 2007 __ sw(at, MemOperand(t1)); |
| 2008 __ Addu(a0, a0, Operand(1)); |
| 2009 __ Branch(&loop); |
| 2010 __ bind(&done_loop); |
| 2011 } |
| 2012 |
| 2013 // Call the [[BoundTargetFunction]] via the Call builtin. |
| 2014 __ lw(a1, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset)); |
| 2015 __ li(at, Operand(ExternalReference(Builtins::kCall_ReceiverIsAny, |
| 2016 masm->isolate()))); |
| 2017 __ lw(at, MemOperand(at)); |
| 2018 __ Addu(at, at, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 2019 __ Jump(at); |
| 2020 } |
| 2021 |
| 2022 |
| 2023 // static |
1929 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { | 2024 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { |
1930 // ----------- S t a t e ------------- | 2025 // ----------- S t a t e ------------- |
1931 // -- a0 : the number of arguments (not including the receiver) | 2026 // -- a0 : the number of arguments (not including the receiver) |
1932 // -- a1 : the target to call (can be any Object). | 2027 // -- a1 : the target to call (can be any Object). |
1933 // ----------------------------------- | 2028 // ----------------------------------- |
1934 | 2029 |
1935 Label non_callable, non_function, non_smi; | 2030 Label non_callable, non_function, non_smi; |
1936 __ JumpIfSmi(a1, &non_callable); | 2031 __ JumpIfSmi(a1, &non_callable); |
1937 __ bind(&non_smi); | 2032 __ bind(&non_smi); |
1938 __ GetObjectType(a1, t1, t2); | 2033 __ GetObjectType(a1, t1, t2); |
1939 __ Jump(masm->isolate()->builtins()->CallFunction(mode), | 2034 __ Jump(masm->isolate()->builtins()->CallFunction(mode), |
1940 RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE)); | 2035 RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE)); |
| 2036 __ Jump(masm->isolate()->builtins()->CallBoundFunction(), |
| 2037 RelocInfo::CODE_TARGET, eq, t2, Operand(JS_BOUND_FUNCTION_TYPE)); |
1941 __ Branch(&non_function, ne, t2, Operand(JS_PROXY_TYPE)); | 2038 __ Branch(&non_function, ne, t2, Operand(JS_PROXY_TYPE)); |
1942 | 2039 |
1943 // 1. Runtime fallback for Proxy [[Call]]. | 2040 // 1. Runtime fallback for Proxy [[Call]]. |
1944 __ Push(a1); | 2041 __ Push(a1); |
1945 // Increase the arguments size to include the pushed function and the | 2042 // Increase the arguments size to include the pushed function and the |
1946 // existing receiver on the stack. | 2043 // existing receiver on the stack. |
1947 __ Addu(a0, a0, 2); | 2044 __ Addu(a0, a0, 2); |
1948 // Tail-call to the runtime. | 2045 // Tail-call to the runtime. |
1949 __ JumpToExternalReference( | 2046 __ JumpToExternalReference( |
1950 ExternalReference(Runtime::kJSProxyCall, masm->isolate())); | 2047 ExternalReference(Runtime::kJSProxyCall, masm->isolate())); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1992 // Tail call to the function-specific construct stub (still in the caller | 2089 // Tail call to the function-specific construct stub (still in the caller |
1993 // context at this point). | 2090 // context at this point). |
1994 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 2091 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
1995 __ lw(t0, FieldMemOperand(t0, SharedFunctionInfo::kConstructStubOffset)); | 2092 __ lw(t0, FieldMemOperand(t0, SharedFunctionInfo::kConstructStubOffset)); |
1996 __ Addu(at, t0, Operand(Code::kHeaderSize - kHeapObjectTag)); | 2093 __ Addu(at, t0, Operand(Code::kHeaderSize - kHeapObjectTag)); |
1997 __ Jump(at); | 2094 __ Jump(at); |
1998 } | 2095 } |
1999 | 2096 |
2000 | 2097 |
2001 // static | 2098 // static |
| 2099 void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) { |
| 2100 // ----------- S t a t e ------------- |
| 2101 // -- a0 : the number of arguments (not including the receiver) |
| 2102 // -- a1 : the function to call (checked to be a JSBoundFunction) |
| 2103 // -- a3 : the new target (checked to be a constructor) |
| 2104 // ----------------------------------- |
| 2105 __ AssertBoundFunction(a1); |
| 2106 |
| 2107 // Load [[BoundArguments]] into a2 and length of that into t0. |
| 2108 __ lw(a2, FieldMemOperand(a1, JSBoundFunction::kBoundArgumentsOffset)); |
| 2109 __ lw(t0, FieldMemOperand(a2, FixedArray::kLengthOffset)); |
| 2110 __ SmiUntag(t0); |
| 2111 |
| 2112 // ----------- S t a t e ------------- |
| 2113 // -- a0 : the number of arguments (not including the receiver) |
| 2114 // -- a1 : the function to call (checked to be a JSBoundFunction) |
| 2115 // -- a2 : the [[BoundArguments]] (implemented as FixedArray) |
| 2116 // -- a3 : the new target (checked to be a constructor) |
| 2117 // -- t0 : the number of [[BoundArguments]] |
| 2118 // ----------------------------------- |
| 2119 |
| 2120 // Reserve stack space for the [[BoundArguments]]. |
| 2121 { |
| 2122 Label done; |
| 2123 __ sll(t1, t0, kPointerSizeLog2); |
| 2124 __ Subu(sp, sp, Operand(t1)); |
| 2125 // Check the stack for overflow. We are not trying to catch interruptions |
| 2126 // (i.e. debug break and preemption) here, so check the "real stack limit". |
| 2127 __ LoadRoot(at, Heap::kRealStackLimitRootIndex); |
| 2128 __ Branch(&done, gt, sp, Operand(at)); // Signed comparison. |
| 2129 // Restore the stack pointer. |
| 2130 __ Addu(sp, sp, Operand(t1)); |
| 2131 { |
| 2132 FrameScope scope(masm, StackFrame::MANUAL); |
| 2133 __ EnterFrame(StackFrame::INTERNAL); |
| 2134 __ CallRuntime(Runtime::kThrowStackOverflow, 0); |
| 2135 } |
| 2136 __ bind(&done); |
| 2137 } |
| 2138 |
| 2139 // Relocate arguments down the stack. |
| 2140 { |
| 2141 Label loop, done_loop; |
| 2142 __ mov(t1, zero_reg); |
| 2143 __ bind(&loop); |
| 2144 __ Branch(&done_loop, ge, t1, Operand(a0)); |
| 2145 __ sll(t2, t0, kPointerSizeLog2); |
| 2146 __ addu(t2, t2, sp); |
| 2147 __ lw(at, MemOperand(t2)); |
| 2148 __ sll(t2, t1, kPointerSizeLog2); |
| 2149 __ addu(t2, t2, sp); |
| 2150 __ sw(at, MemOperand(t2)); |
| 2151 __ Addu(t0, t0, Operand(1)); |
| 2152 __ Addu(t1, t1, Operand(1)); |
| 2153 __ Branch(&loop); |
| 2154 __ bind(&done_loop); |
| 2155 } |
| 2156 |
| 2157 // Copy [[BoundArguments]] to the stack (below the arguments). |
| 2158 { |
| 2159 Label loop, done_loop; |
| 2160 __ lw(t0, FieldMemOperand(a2, FixedArray::kLengthOffset)); |
| 2161 __ SmiUntag(t0); |
| 2162 __ Addu(a2, a2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 2163 __ bind(&loop); |
| 2164 __ Subu(t0, t0, Operand(1)); |
| 2165 __ Branch(&done_loop, lt, t0, Operand(zero_reg)); |
| 2166 __ sll(t1, t0, kPointerSizeLog2); |
| 2167 __ addu(t1, t1, a2); |
| 2168 __ lw(at, MemOperand(t1)); |
| 2169 __ sll(t1, a0, kPointerSizeLog2); |
| 2170 __ addu(t1, t1, sp); |
| 2171 __ sw(at, MemOperand(t1)); |
| 2172 __ Addu(a0, a0, Operand(1)); |
| 2173 __ Branch(&loop); |
| 2174 __ bind(&done_loop); |
| 2175 } |
| 2176 |
| 2177 // Patch new.target to [[BoundTargetFunction]] if new.target equals target. |
| 2178 { |
| 2179 Label skip_load; |
| 2180 __ Branch(&skip_load, ne, a1, Operand(a3)); |
| 2181 __ lw(a3, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset)); |
| 2182 __ bind(&skip_load); |
| 2183 } |
| 2184 |
| 2185 // Construct the [[BoundTargetFunction]] via the Construct builtin. |
| 2186 __ lw(a1, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset)); |
| 2187 __ li(at, Operand(ExternalReference(Builtins::kConstruct, masm->isolate()))); |
| 2188 __ lw(at, MemOperand(at)); |
| 2189 __ Addu(at, at, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 2190 __ Jump(at); |
| 2191 } |
| 2192 |
| 2193 |
| 2194 // static |
2002 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { | 2195 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { |
2003 // ----------- S t a t e ------------- | 2196 // ----------- S t a t e ------------- |
2004 // -- a0 : the number of arguments (not including the receiver) | 2197 // -- a0 : the number of arguments (not including the receiver) |
2005 // -- a1 : the constructor to call (checked to be a JSProxy) | 2198 // -- a1 : the constructor to call (checked to be a JSProxy) |
2006 // -- a3 : the new target (either the same as the constructor or | 2199 // -- a3 : the new target (either the same as the constructor or |
2007 // the JSFunction on which new was invoked initially) | 2200 // the JSFunction on which new was invoked initially) |
2008 // ----------------------------------- | 2201 // ----------------------------------- |
2009 | 2202 |
2010 // Call into the Runtime for Proxy [[Construct]]. | 2203 // Call into the Runtime for Proxy [[Construct]]. |
2011 __ Push(a1, a3); | 2204 __ Push(a1, a3); |
(...skipping 22 matching lines...) Expand all Loading... |
2034 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset)); | 2227 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset)); |
2035 __ lbu(t2, FieldMemOperand(t1, Map::kInstanceTypeOffset)); | 2228 __ lbu(t2, FieldMemOperand(t1, Map::kInstanceTypeOffset)); |
2036 __ Jump(masm->isolate()->builtins()->ConstructFunction(), | 2229 __ Jump(masm->isolate()->builtins()->ConstructFunction(), |
2037 RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE)); | 2230 RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE)); |
2038 | 2231 |
2039 // Check if target has a [[Construct]] internal method. | 2232 // Check if target has a [[Construct]] internal method. |
2040 __ lbu(t3, FieldMemOperand(t1, Map::kBitFieldOffset)); | 2233 __ lbu(t3, FieldMemOperand(t1, Map::kBitFieldOffset)); |
2041 __ And(t3, t3, Operand(1 << Map::kIsCallable)); | 2234 __ And(t3, t3, Operand(1 << Map::kIsCallable)); |
2042 __ Branch(&non_constructor, eq, t3, Operand(zero_reg)); | 2235 __ Branch(&non_constructor, eq, t3, Operand(zero_reg)); |
2043 | 2236 |
| 2237 // Only dispatch to bound functions after checking whether they are |
| 2238 // constructors. |
| 2239 __ Jump(masm->isolate()->builtins()->ConstructBoundFunction(), |
| 2240 RelocInfo::CODE_TARGET, eq, t2, Operand(JS_BOUND_FUNCTION_TYPE)); |
| 2241 |
2044 // Only dispatch to proxies after checking whether they are constructors. | 2242 // Only dispatch to proxies after checking whether they are constructors. |
2045 __ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET, | 2243 __ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET, |
2046 eq, t2, Operand(JS_PROXY_TYPE)); | 2244 eq, t2, Operand(JS_PROXY_TYPE)); |
2047 | 2245 |
2048 // Called Construct on an exotic Object with a [[Construct]] internal method. | 2246 // Called Construct on an exotic Object with a [[Construct]] internal method. |
2049 { | 2247 { |
2050 // Overwrite the original receiver with the (original) target. | 2248 // Overwrite the original receiver with the (original) target. |
2051 __ sll(at, a0, kPointerSizeLog2); | 2249 __ sll(at, a0, kPointerSizeLog2); |
2052 __ addu(at, sp, at); | 2250 __ addu(at, sp, at); |
2053 __ sw(a1, MemOperand(at)); | 2251 __ sw(a1, MemOperand(at)); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2219 } | 2417 } |
2220 } | 2418 } |
2221 | 2419 |
2222 | 2420 |
2223 #undef __ | 2421 #undef __ |
2224 | 2422 |
2225 } // namespace internal | 2423 } // namespace internal |
2226 } // namespace v8 | 2424 } // namespace v8 |
2227 | 2425 |
2228 #endif // V8_TARGET_ARCH_MIPS | 2426 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |