OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_PPC | 5 #if V8_TARGET_ARCH_PPC |
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 1915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1926 // The function is a "classConstructor", need to raise an exception. | 1926 // The function is a "classConstructor", need to raise an exception. |
1927 __ bind(&class_constructor); | 1927 __ bind(&class_constructor); |
1928 { | 1928 { |
1929 FrameAndConstantPoolScope frame(masm, StackFrame::INTERNAL); | 1929 FrameAndConstantPoolScope frame(masm, StackFrame::INTERNAL); |
1930 __ push(r4); | 1930 __ push(r4); |
1931 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 1); | 1931 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 1); |
1932 } | 1932 } |
1933 } | 1933 } |
1934 | 1934 |
1935 | 1935 |
| 1936 namespace { |
| 1937 |
| 1938 void Generate_PushBoundArguments(MacroAssembler* masm) { |
| 1939 // ----------- S t a t e ------------- |
| 1940 // -- r3 : the number of arguments (not including the receiver) |
| 1941 // -- r4 : target (checked to be a JSBoundFunction) |
| 1942 // -- r6 : new.target (only in case of [[Construct]]) |
| 1943 // ----------------------------------- |
| 1944 |
| 1945 // Load [[BoundArguments]] into r5 and length of that into r7. |
| 1946 Label no_bound_arguments; |
| 1947 __ LoadP(r5, FieldMemOperand(r4, JSBoundFunction::kBoundArgumentsOffset)); |
| 1948 __ LoadP(r7, FieldMemOperand(r5, FixedArray::kLengthOffset)); |
| 1949 __ SmiUntag(r7, SetRC); |
| 1950 __ beq(&no_bound_arguments, cr0); |
| 1951 { |
| 1952 // ----------- S t a t e ------------- |
| 1953 // -- r3 : the number of arguments (not including the receiver) |
| 1954 // -- r4 : target (checked to be a JSBoundFunction) |
| 1955 // -- r5 : the [[BoundArguments]] (implemented as FixedArray) |
| 1956 // -- r6 : new.target (only in case of [[Construct]]) |
| 1957 // -- r7 : the number of [[BoundArguments]] |
| 1958 // ----------------------------------- |
| 1959 |
| 1960 // Reserve stack space for the [[BoundArguments]]. |
| 1961 { |
| 1962 Label done; |
| 1963 __ mr(r9, sp); // preserve previous stack pointer |
| 1964 __ ShiftLeftImm(r10, r7, Operand(kPointerSizeLog2)); |
| 1965 __ sub(sp, sp, r10); |
| 1966 // Check the stack for overflow. We are not trying to catch interruptions |
| 1967 // (i.e. debug break and preemption) here, so check the "real stack |
| 1968 // limit". |
| 1969 __ CompareRoot(sp, Heap::kRealStackLimitRootIndex); |
| 1970 __ bgt(&done); // Signed comparison. |
| 1971 // Restore the stack pointer. |
| 1972 __ mr(sp, r9); |
| 1973 { |
| 1974 FrameScope scope(masm, StackFrame::MANUAL); |
| 1975 __ EnterFrame(StackFrame::INTERNAL); |
| 1976 __ CallRuntime(Runtime::kThrowStackOverflow, 0); |
| 1977 } |
| 1978 __ bind(&done); |
| 1979 } |
| 1980 |
| 1981 // Relocate arguments down the stack. |
| 1982 // -- r3 : the number of arguments (not including the receiver) |
| 1983 // -- r9 : the previous stack pointer |
| 1984 // -- r10: the size of the [[BoundArguments]] |
| 1985 { |
| 1986 Label skip, loop; |
| 1987 __ li(r8, Operand::Zero()); |
| 1988 __ cmpi(r3, Operand::Zero()); |
| 1989 __ beq(&skip); |
| 1990 __ mtctr(r3); |
| 1991 __ bind(&loop); |
| 1992 __ LoadPX(r0, MemOperand(r9, r8)); |
| 1993 __ StorePX(r0, MemOperand(sp, r8)); |
| 1994 __ addi(r8, r8, Operand(kPointerSize)); |
| 1995 __ bdnz(&loop); |
| 1996 __ bind(&skip); |
| 1997 } |
| 1998 |
| 1999 // Copy [[BoundArguments]] to the stack (below the arguments). |
| 2000 { |
| 2001 Label loop; |
| 2002 __ addi(r5, r5, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 2003 __ add(r5, r5, r10); |
| 2004 __ mtctr(r7); |
| 2005 __ bind(&loop); |
| 2006 __ LoadPU(r0, MemOperand(r5, -kPointerSize)); |
| 2007 __ StorePX(r0, MemOperand(sp, r8)); |
| 2008 __ addi(r8, r8, Operand(kPointerSize)); |
| 2009 __ bdnz(&loop); |
| 2010 __ add(r3, r3, r7); |
| 2011 } |
| 2012 } |
| 2013 __ bind(&no_bound_arguments); |
| 2014 } |
| 2015 |
| 2016 } // namespace |
| 2017 |
| 2018 |
| 2019 // static |
| 2020 void Builtins::Generate_CallBoundFunction(MacroAssembler* masm) { |
| 2021 // ----------- S t a t e ------------- |
| 2022 // -- r3 : the number of arguments (not including the receiver) |
| 2023 // -- r4 : the function to call (checked to be a JSBoundFunction) |
| 2024 // ----------------------------------- |
| 2025 __ AssertBoundFunction(r4); |
| 2026 |
| 2027 // Patch the receiver to [[BoundThis]]. |
| 2028 __ LoadP(ip, FieldMemOperand(r4, JSBoundFunction::kBoundThisOffset)); |
| 2029 __ ShiftLeftImm(r0, r3, Operand(kPointerSizeLog2)); |
| 2030 __ StorePX(ip, MemOperand(sp, r0)); |
| 2031 |
| 2032 // Push the [[BoundArguments]] onto the stack. |
| 2033 Generate_PushBoundArguments(masm); |
| 2034 |
| 2035 // Call the [[BoundTargetFunction]] via the Call builtin. |
| 2036 __ LoadP(r4, |
| 2037 FieldMemOperand(r4, JSBoundFunction::kBoundTargetFunctionOffset)); |
| 2038 __ mov(ip, Operand(ExternalReference(Builtins::kCall_ReceiverIsAny, |
| 2039 masm->isolate()))); |
| 2040 __ LoadP(ip, MemOperand(ip)); |
| 2041 __ addi(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 2042 __ JumpToJSEntry(ip); |
| 2043 } |
| 2044 |
| 2045 |
1936 // static | 2046 // static |
1937 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { | 2047 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { |
1938 // ----------- S t a t e ------------- | 2048 // ----------- S t a t e ------------- |
1939 // -- r3 : the number of arguments (not including the receiver) | 2049 // -- r3 : the number of arguments (not including the receiver) |
1940 // -- r4 : the target to call (can be any Object). | 2050 // -- r4 : the target to call (can be any Object). |
1941 // ----------------------------------- | 2051 // ----------------------------------- |
1942 | 2052 |
1943 Label non_callable, non_function, non_smi; | 2053 Label non_callable, non_function, non_smi; |
1944 __ JumpIfSmi(r4, &non_callable); | 2054 __ JumpIfSmi(r4, &non_callable); |
1945 __ bind(&non_smi); | 2055 __ bind(&non_smi); |
1946 __ CompareObjectType(r4, r7, r8, JS_FUNCTION_TYPE); | 2056 __ CompareObjectType(r4, r7, r8, JS_FUNCTION_TYPE); |
1947 __ Jump(masm->isolate()->builtins()->CallFunction(mode), | 2057 __ Jump(masm->isolate()->builtins()->CallFunction(mode), |
1948 RelocInfo::CODE_TARGET, eq); | 2058 RelocInfo::CODE_TARGET, eq); |
| 2059 __ cmpi(r8, Operand(JS_BOUND_FUNCTION_TYPE)); |
| 2060 __ Jump(masm->isolate()->builtins()->CallBoundFunction(), |
| 2061 RelocInfo::CODE_TARGET, eq); |
1949 __ cmpi(r8, Operand(JS_PROXY_TYPE)); | 2062 __ cmpi(r8, Operand(JS_PROXY_TYPE)); |
1950 __ bne(&non_function); | 2063 __ bne(&non_function); |
1951 | 2064 |
1952 // 1. Runtime fallback for Proxy [[Call]]. | 2065 // 1. Runtime fallback for Proxy [[Call]]. |
1953 __ Push(r4); | 2066 __ Push(r4); |
1954 // Increase the arguments size to include the pushed function and the | 2067 // Increase the arguments size to include the pushed function and the |
1955 // existing receiver on the stack. | 2068 // existing receiver on the stack. |
1956 __ addi(r3, r3, Operand(2)); | 2069 __ addi(r3, r3, Operand(2)); |
1957 // Tail-call to the runtime. | 2070 // Tail-call to the runtime. |
1958 __ JumpToExternalReference( | 2071 __ JumpToExternalReference( |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2000 // Tail call to the function-specific construct stub (still in the caller | 2113 // Tail call to the function-specific construct stub (still in the caller |
2001 // context at this point). | 2114 // context at this point). |
2002 __ LoadP(r7, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); | 2115 __ LoadP(r7, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); |
2003 __ LoadP(r7, FieldMemOperand(r7, SharedFunctionInfo::kConstructStubOffset)); | 2116 __ LoadP(r7, FieldMemOperand(r7, SharedFunctionInfo::kConstructStubOffset)); |
2004 __ addi(ip, r7, Operand(Code::kHeaderSize - kHeapObjectTag)); | 2117 __ addi(ip, r7, Operand(Code::kHeaderSize - kHeapObjectTag)); |
2005 __ JumpToJSEntry(ip); | 2118 __ JumpToJSEntry(ip); |
2006 } | 2119 } |
2007 | 2120 |
2008 | 2121 |
2009 // static | 2122 // static |
| 2123 void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) { |
| 2124 // ----------- S t a t e ------------- |
| 2125 // -- r3 : the number of arguments (not including the receiver) |
| 2126 // -- r4 : the function to call (checked to be a JSBoundFunction) |
| 2127 // -- r6 : the new target (checked to be a constructor) |
| 2128 // ----------------------------------- |
| 2129 __ AssertBoundFunction(r4); |
| 2130 |
| 2131 // Push the [[BoundArguments]] onto the stack. |
| 2132 Generate_PushBoundArguments(masm); |
| 2133 |
| 2134 // Patch new.target to [[BoundTargetFunction]] if new.target equals target. |
| 2135 Label skip; |
| 2136 __ cmp(r4, r6); |
| 2137 __ bne(&skip); |
| 2138 __ LoadP(r6, |
| 2139 FieldMemOperand(r4, JSBoundFunction::kBoundTargetFunctionOffset)); |
| 2140 __ bind(&skip); |
| 2141 |
| 2142 // Construct the [[BoundTargetFunction]] via the Construct builtin. |
| 2143 __ LoadP(r4, |
| 2144 FieldMemOperand(r4, JSBoundFunction::kBoundTargetFunctionOffset)); |
| 2145 __ mov(ip, Operand(ExternalReference(Builtins::kConstruct, masm->isolate()))); |
| 2146 __ LoadP(ip, MemOperand(ip)); |
| 2147 __ addi(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 2148 __ JumpToJSEntry(ip); |
| 2149 } |
| 2150 |
| 2151 |
| 2152 // static |
2010 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { | 2153 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { |
2011 // ----------- S t a t e ------------- | 2154 // ----------- S t a t e ------------- |
2012 // -- r3 : the number of arguments (not including the receiver) | 2155 // -- r3 : the number of arguments (not including the receiver) |
2013 // -- r4 : the constructor to call (checked to be a JSProxy) | 2156 // -- r4 : the constructor to call (checked to be a JSProxy) |
2014 // -- r6 : the new target (either the same as the constructor or | 2157 // -- r6 : the new target (either the same as the constructor or |
2015 // the JSFunction on which new was invoked initially) | 2158 // the JSFunction on which new was invoked initially) |
2016 // ----------------------------------- | 2159 // ----------------------------------- |
2017 | 2160 |
2018 // Call into the Runtime for Proxy [[Construct]]. | 2161 // Call into the Runtime for Proxy [[Construct]]. |
2019 __ Push(r4, r6); | 2162 __ Push(r4, r6); |
(...skipping 21 matching lines...) Expand all Loading... |
2041 // Dispatch based on instance type. | 2184 // Dispatch based on instance type. |
2042 __ CompareObjectType(r4, r7, r8, JS_FUNCTION_TYPE); | 2185 __ CompareObjectType(r4, r7, r8, JS_FUNCTION_TYPE); |
2043 __ Jump(masm->isolate()->builtins()->ConstructFunction(), | 2186 __ Jump(masm->isolate()->builtins()->ConstructFunction(), |
2044 RelocInfo::CODE_TARGET, eq); | 2187 RelocInfo::CODE_TARGET, eq); |
2045 | 2188 |
2046 // Check if target has a [[Construct]] internal method. | 2189 // Check if target has a [[Construct]] internal method. |
2047 __ lbz(r5, FieldMemOperand(r7, Map::kBitFieldOffset)); | 2190 __ lbz(r5, FieldMemOperand(r7, Map::kBitFieldOffset)); |
2048 __ TestBit(r5, Map::kIsConstructor, r0); | 2191 __ TestBit(r5, Map::kIsConstructor, r0); |
2049 __ beq(&non_constructor, cr0); | 2192 __ beq(&non_constructor, cr0); |
2050 | 2193 |
| 2194 // Only dispatch to bound functions after checking whether they are |
| 2195 // constructors. |
| 2196 __ cmpi(r8, Operand(JS_BOUND_FUNCTION_TYPE)); |
| 2197 __ Jump(masm->isolate()->builtins()->ConstructBoundFunction(), |
| 2198 RelocInfo::CODE_TARGET, eq); |
| 2199 |
2051 // Only dispatch to proxies after checking whether they are constructors. | 2200 // Only dispatch to proxies after checking whether they are constructors. |
2052 __ cmpi(r8, Operand(JS_PROXY_TYPE)); | 2201 __ cmpi(r8, Operand(JS_PROXY_TYPE)); |
2053 __ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET, | 2202 __ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET, |
2054 eq); | 2203 eq); |
2055 | 2204 |
2056 // Called Construct on an exotic Object with a [[Construct]] internal method. | 2205 // Called Construct on an exotic Object with a [[Construct]] internal method. |
2057 { | 2206 { |
2058 // Overwrite the original receiver with the (original) target. | 2207 // Overwrite the original receiver with the (original) target. |
2059 __ ShiftLeftImm(r8, r3, Operand(kPointerSizeLog2)); | 2208 __ ShiftLeftImm(r8, r3, Operand(kPointerSizeLog2)); |
2060 __ StorePX(r4, MemOperand(sp, r8)); | 2209 __ StorePX(r4, MemOperand(sp, r8)); |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2229 __ bkpt(0); | 2378 __ bkpt(0); |
2230 } | 2379 } |
2231 } | 2380 } |
2232 | 2381 |
2233 | 2382 |
2234 #undef __ | 2383 #undef __ |
2235 } // namespace internal | 2384 } // namespace internal |
2236 } // namespace v8 | 2385 } // namespace v8 |
2237 | 2386 |
2238 #endif // V8_TARGET_ARCH_PPC | 2387 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |