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_ARM | 5 #if V8_TARGET_ARCH_ARM |
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 1876 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1887 __ bind(&class_constructor); | 1887 __ bind(&class_constructor); |
1888 { | 1888 { |
1889 FrameScope frame(masm, StackFrame::INTERNAL); | 1889 FrameScope frame(masm, StackFrame::INTERNAL); |
1890 __ push(r1); | 1890 __ push(r1); |
1891 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 1); | 1891 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 1); |
1892 } | 1892 } |
1893 } | 1893 } |
1894 | 1894 |
1895 | 1895 |
1896 // static | 1896 // static |
| 1897 void Builtins::Generate_CallBoundFunction(MacroAssembler* masm) { |
| 1898 // ----------- S t a t e ------------- |
| 1899 // -- r0 : the number of arguments (not including the receiver) |
| 1900 // -- r1 : the function to call (checked to be a JSBoundFunction) |
| 1901 // ----------------------------------- |
| 1902 __ AssertBoundFunction(r1); |
| 1903 |
| 1904 // Patch the receiver to [[BoundThis]]. |
| 1905 { |
| 1906 __ ldr(ip, FieldMemOperand(r1, JSBoundFunction::kBoundThisOffset)); |
| 1907 __ str(ip, MemOperand(sp, r0, LSL, kPointerSizeLog2)); |
| 1908 } |
| 1909 |
| 1910 // Load [[BoundArguments]] into r2 and length of that into r4. |
| 1911 __ ldr(r2, FieldMemOperand(r1, JSBoundFunction::kBoundArgumentsOffset)); |
| 1912 __ ldr(r4, FieldMemOperand(r2, FixedArray::kLengthOffset)); |
| 1913 __ SmiUntag(r4); |
| 1914 |
| 1915 // ----------- S t a t e ------------- |
| 1916 // -- r0 : the number of arguments (not including the receiver) |
| 1917 // -- r1 : the function to call (checked to be a JSBoundFunction) |
| 1918 // -- r2 : the [[BoundArguments]] (implemented as FixedArray) |
| 1919 // -- r4 : the number of [[BoundArguments]] |
| 1920 // ----------------------------------- |
| 1921 |
| 1922 // Reserve stack space for the [[BoundArguments]]. |
| 1923 { |
| 1924 Label done; |
| 1925 __ sub(sp, sp, Operand(r4, LSL, kPointerSizeLog2)); |
| 1926 // Check the stack for overflow. We are not trying to catch interruptions |
| 1927 // (i.e. debug break and preemption) here, so check the "real stack limit". |
| 1928 __ CompareRoot(sp, Heap::kRealStackLimitRootIndex); |
| 1929 __ b(gt, &done); // Signed comparison. |
| 1930 // Restore the stack pointer. |
| 1931 __ add(sp, sp, Operand(r4, LSL, kPointerSizeLog2)); |
| 1932 { |
| 1933 FrameScope scope(masm, StackFrame::MANUAL); |
| 1934 __ EnterFrame(StackFrame::INTERNAL); |
| 1935 __ CallRuntime(Runtime::kThrowStackOverflow, 0); |
| 1936 } |
| 1937 __ bind(&done); |
| 1938 } |
| 1939 |
| 1940 // Relocate arguments down the stack. |
| 1941 { |
| 1942 Label loop, done_loop; |
| 1943 __ mov(r5, Operand(0)); |
| 1944 __ bind(&loop); |
| 1945 __ cmp(r5, r0); |
| 1946 __ b(gt, &done_loop); |
| 1947 __ ldr(ip, MemOperand(sp, r4, LSL, kPointerSizeLog2)); |
| 1948 __ str(ip, MemOperand(sp, r5, LSL, kPointerSizeLog2)); |
| 1949 __ add(r4, r4, Operand(1)); |
| 1950 __ add(r5, r5, Operand(1)); |
| 1951 __ b(&loop); |
| 1952 __ bind(&done_loop); |
| 1953 } |
| 1954 |
| 1955 // Copy [[BoundArguments]] to the stack (below the arguments). |
| 1956 { |
| 1957 Label loop, done_loop; |
| 1958 __ ldr(r4, FieldMemOperand(r2, FixedArray::kLengthOffset)); |
| 1959 __ SmiUntag(r4); |
| 1960 __ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 1961 __ bind(&loop); |
| 1962 __ sub(r4, r4, Operand(1), SetCC); |
| 1963 __ b(lt, &done_loop); |
| 1964 __ ldr(ip, MemOperand(r2, r4, LSL, kPointerSizeLog2)); |
| 1965 __ str(ip, MemOperand(sp, r0, LSL, kPointerSizeLog2)); |
| 1966 __ add(r0, r0, Operand(1)); |
| 1967 __ b(&loop); |
| 1968 __ bind(&done_loop); |
| 1969 } |
| 1970 |
| 1971 // Call the [[BoundTargetFunction]] via the Call builtin. |
| 1972 __ ldr(r1, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset)); |
| 1973 __ mov(ip, Operand(ExternalReference(Builtins::kCall_ReceiverIsAny, |
| 1974 masm->isolate()))); |
| 1975 __ ldr(ip, MemOperand(ip)); |
| 1976 __ add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 1977 } |
| 1978 |
| 1979 |
| 1980 // static |
1897 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { | 1981 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { |
1898 // ----------- S t a t e ------------- | 1982 // ----------- S t a t e ------------- |
1899 // -- r0 : the number of arguments (not including the receiver) | 1983 // -- r0 : the number of arguments (not including the receiver) |
1900 // -- r1 : the target to call (can be any Object). | 1984 // -- r1 : the target to call (can be any Object). |
1901 // ----------------------------------- | 1985 // ----------------------------------- |
1902 | 1986 |
1903 Label non_callable, non_function, non_smi; | 1987 Label non_callable, non_function, non_smi; |
1904 __ JumpIfSmi(r1, &non_callable); | 1988 __ JumpIfSmi(r1, &non_callable); |
1905 __ bind(&non_smi); | 1989 __ bind(&non_smi); |
1906 __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE); | 1990 __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE); |
1907 __ Jump(masm->isolate()->builtins()->CallFunction(mode), | 1991 __ Jump(masm->isolate()->builtins()->CallFunction(mode), |
1908 RelocInfo::CODE_TARGET, eq); | 1992 RelocInfo::CODE_TARGET, eq); |
| 1993 __ cmp(r5, Operand(JS_BOUND_FUNCTION_TYPE)); |
| 1994 __ Jump(masm->isolate()->builtins()->CallBoundFunction(), |
| 1995 RelocInfo::CODE_TARGET, eq); |
1909 __ cmp(r5, Operand(JS_PROXY_TYPE)); | 1996 __ cmp(r5, Operand(JS_PROXY_TYPE)); |
1910 __ b(ne, &non_function); | 1997 __ b(ne, &non_function); |
1911 | 1998 |
1912 // 1. Runtime fallback for Proxy [[Call]]. | 1999 // 1. Runtime fallback for Proxy [[Call]]. |
1913 __ Push(r1); | 2000 __ Push(r1); |
1914 // Increase the arguments size to include the pushed function and the | 2001 // Increase the arguments size to include the pushed function and the |
1915 // existing receiver on the stack. | 2002 // existing receiver on the stack. |
1916 __ add(r0, r0, Operand(2)); | 2003 __ add(r0, r0, Operand(2)); |
1917 // Tail-call to the runtime. | 2004 // Tail-call to the runtime. |
1918 __ JumpToExternalReference( | 2005 __ JumpToExternalReference( |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1958 | 2045 |
1959 // Tail call to the function-specific construct stub (still in the caller | 2046 // Tail call to the function-specific construct stub (still in the caller |
1960 // context at this point). | 2047 // context at this point). |
1961 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | 2048 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
1962 __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset)); | 2049 __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset)); |
1963 __ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag)); | 2050 __ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag)); |
1964 } | 2051 } |
1965 | 2052 |
1966 | 2053 |
1967 // static | 2054 // static |
| 2055 void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) { |
| 2056 // ----------- S t a t e ------------- |
| 2057 // -- r0 : the number of arguments (not including the receiver) |
| 2058 // -- r1 : the function to call (checked to be a JSBoundFunction) |
| 2059 // -- r3 : the new target (checked to be a constructor) |
| 2060 // ----------------------------------- |
| 2061 __ AssertBoundFunction(r1); |
| 2062 |
| 2063 // Load [[BoundArguments]] into r2 and length of that into r4. |
| 2064 __ ldr(r2, FieldMemOperand(r1, JSBoundFunction::kBoundArgumentsOffset)); |
| 2065 __ ldr(r4, FieldMemOperand(r2, FixedArray::kLengthOffset)); |
| 2066 __ SmiUntag(r4); |
| 2067 |
| 2068 // ----------- S t a t e ------------- |
| 2069 // -- r0 : the number of arguments (not including the receiver) |
| 2070 // -- r1 : the function to call (checked to be a JSBoundFunction) |
| 2071 // -- r2 : the [[BoundArguments]] (implemented as FixedArray) |
| 2072 // -- r3 : the new target (checked to be a constructor) |
| 2073 // -- r4 : the number of [[BoundArguments]] |
| 2074 // ----------------------------------- |
| 2075 |
| 2076 // Reserve stack space for the [[BoundArguments]]. |
| 2077 { |
| 2078 Label done; |
| 2079 __ sub(sp, sp, Operand(r4, LSL, kPointerSizeLog2)); |
| 2080 // Check the stack for overflow. We are not trying to catch interruptions |
| 2081 // (i.e. debug break and preemption) here, so check the "real stack limit". |
| 2082 __ CompareRoot(sp, Heap::kRealStackLimitRootIndex); |
| 2083 __ b(gt, &done); // Signed comparison. |
| 2084 // Restore the stack pointer. |
| 2085 __ add(sp, sp, Operand(r4, LSL, kPointerSizeLog2)); |
| 2086 { |
| 2087 FrameScope scope(masm, StackFrame::MANUAL); |
| 2088 __ EnterFrame(StackFrame::INTERNAL); |
| 2089 __ CallRuntime(Runtime::kThrowStackOverflow, 0); |
| 2090 } |
| 2091 __ bind(&done); |
| 2092 } |
| 2093 |
| 2094 // Relocate arguments down the stack. |
| 2095 { |
| 2096 Label loop, done_loop; |
| 2097 __ mov(r5, Operand(0)); |
| 2098 __ bind(&loop); |
| 2099 __ cmp(r5, r0); |
| 2100 __ b(ge, &done_loop); |
| 2101 __ ldr(ip, MemOperand(sp, r4, LSL, kPointerSizeLog2)); |
| 2102 __ str(ip, MemOperand(sp, r5, LSL, kPointerSizeLog2)); |
| 2103 __ add(r4, r4, Operand(1)); |
| 2104 __ add(r5, r5, Operand(1)); |
| 2105 __ b(&loop); |
| 2106 __ bind(&done_loop); |
| 2107 } |
| 2108 |
| 2109 // Copy [[BoundArguments]] to the stack (below the arguments). |
| 2110 { |
| 2111 Label loop, done_loop; |
| 2112 __ ldr(r4, FieldMemOperand(r2, FixedArray::kLengthOffset)); |
| 2113 __ SmiUntag(r4); |
| 2114 __ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 2115 __ bind(&loop); |
| 2116 __ sub(r4, r4, Operand(1), SetCC); |
| 2117 __ b(lt, &done_loop); |
| 2118 __ ldr(ip, MemOperand(r2, r4, LSL, kPointerSizeLog2)); |
| 2119 __ str(ip, MemOperand(sp, r0, LSL, kPointerSizeLog2)); |
| 2120 __ add(r0, r0, Operand(1)); |
| 2121 __ b(&loop); |
| 2122 __ bind(&done_loop); |
| 2123 } |
| 2124 |
| 2125 // Patch new.target to [[BoundTargetFunction]] if new.target equals target. |
| 2126 { |
| 2127 __ cmp(r1, r3); |
| 2128 __ ldr(r3, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset), |
| 2129 eq); |
| 2130 } |
| 2131 |
| 2132 // Construct the [[BoundTargetFunction]] via the Construct builtin. |
| 2133 __ ldr(r1, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset)); |
| 2134 __ mov(ip, Operand(ExternalReference(Builtins::kConstruct, masm->isolate()))); |
| 2135 __ ldr(ip, MemOperand(ip)); |
| 2136 __ add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 2137 } |
| 2138 |
| 2139 |
| 2140 // static |
1968 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { | 2141 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { |
1969 // ----------- S t a t e ------------- | 2142 // ----------- S t a t e ------------- |
1970 // -- r0 : the number of arguments (not including the receiver) | 2143 // -- r0 : the number of arguments (not including the receiver) |
1971 // -- r1 : the constructor to call (checked to be a JSProxy) | 2144 // -- r1 : the constructor to call (checked to be a JSProxy) |
1972 // -- r3 : the new target (either the same as the constructor or | 2145 // -- r3 : the new target (either the same as the constructor or |
1973 // the JSFunction on which new was invoked initially) | 2146 // the JSFunction on which new was invoked initially) |
1974 // ----------------------------------- | 2147 // ----------------------------------- |
1975 | 2148 |
1976 // Call into the Runtime for Proxy [[Construct]]. | 2149 // Call into the Runtime for Proxy [[Construct]]. |
1977 __ Push(r1); | 2150 __ Push(r1); |
(...skipping 22 matching lines...) Expand all Loading... |
2000 // Dispatch based on instance type. | 2173 // Dispatch based on instance type. |
2001 __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE); | 2174 __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE); |
2002 __ Jump(masm->isolate()->builtins()->ConstructFunction(), | 2175 __ Jump(masm->isolate()->builtins()->ConstructFunction(), |
2003 RelocInfo::CODE_TARGET, eq); | 2176 RelocInfo::CODE_TARGET, eq); |
2004 | 2177 |
2005 // Check if target has a [[Construct]] internal method. | 2178 // Check if target has a [[Construct]] internal method. |
2006 __ ldrb(r2, FieldMemOperand(r4, Map::kBitFieldOffset)); | 2179 __ ldrb(r2, FieldMemOperand(r4, Map::kBitFieldOffset)); |
2007 __ tst(r2, Operand(1 << Map::kIsConstructor)); | 2180 __ tst(r2, Operand(1 << Map::kIsConstructor)); |
2008 __ b(eq, &non_constructor); | 2181 __ b(eq, &non_constructor); |
2009 | 2182 |
| 2183 // Only dispatch to bound functions after checking whether they are |
| 2184 // constructors. |
| 2185 __ cmp(r5, Operand(JS_BOUND_FUNCTION_TYPE)); |
| 2186 __ Jump(masm->isolate()->builtins()->ConstructBoundFunction(), |
| 2187 RelocInfo::CODE_TARGET, eq); |
| 2188 |
2010 // Only dispatch to proxies after checking whether they are constructors. | 2189 // Only dispatch to proxies after checking whether they are constructors. |
2011 __ cmp(r5, Operand(JS_PROXY_TYPE)); | 2190 __ cmp(r5, Operand(JS_PROXY_TYPE)); |
2012 __ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET, | 2191 __ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET, |
2013 eq); | 2192 eq); |
2014 | 2193 |
2015 // Called Construct on an exotic Object with a [[Construct]] internal method. | 2194 // Called Construct on an exotic Object with a [[Construct]] internal method. |
2016 { | 2195 { |
2017 // Overwrite the original receiver with the (original) target. | 2196 // Overwrite the original receiver with the (original) target. |
2018 __ str(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); | 2197 __ str(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); |
2019 // Let the "call_as_constructor_delegate" take care of the rest. | 2198 // Let the "call_as_constructor_delegate" take care of the rest. |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2175 } | 2354 } |
2176 } | 2355 } |
2177 | 2356 |
2178 | 2357 |
2179 #undef __ | 2358 #undef __ |
2180 | 2359 |
2181 } // namespace internal | 2360 } // namespace internal |
2182 } // namespace v8 | 2361 } // namespace v8 |
2183 | 2362 |
2184 #endif // V8_TARGET_ARCH_ARM | 2363 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |