| 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 1875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1886 // The function is a "classConstructor", need to raise an exception. | 1886 // The function is a "classConstructor", need to raise an exception. |
| 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 namespace { | |
| 1897 | |
| 1898 void Generate_PushBoundArguments(MacroAssembler* masm) { | |
| 1899 // ----------- S t a t e ------------- | |
| 1900 // -- r0 : the number of arguments (not including the receiver) | |
| 1901 // -- r1 : target (checked to be a JSBoundFunction) | |
| 1902 // -- r3 : new.target (only in case of [[Construct]]) | |
| 1903 // ----------------------------------- | |
| 1904 | |
| 1905 // Load [[BoundArguments]] into r2 and length of that into r4. | |
| 1906 Label no_bound_arguments; | |
| 1907 __ ldr(r2, FieldMemOperand(r1, JSBoundFunction::kBoundArgumentsOffset)); | |
| 1908 __ ldr(r4, FieldMemOperand(r2, FixedArray::kLengthOffset)); | |
| 1909 __ SmiUntag(r4); | |
| 1910 __ cmp(r4, Operand(0)); | |
| 1911 __ b(eq, &no_bound_arguments); | |
| 1912 { | |
| 1913 // ----------- S t a t e ------------- | |
| 1914 // -- r0 : the number of arguments (not including the receiver) | |
| 1915 // -- r1 : target (checked to be a JSBoundFunction) | |
| 1916 // -- r2 : the [[BoundArguments]] (implemented as FixedArray) | |
| 1917 // -- r3 : new.target (only in case of [[Construct]]) | |
| 1918 // -- r4 : the number of [[BoundArguments]] | |
| 1919 // ----------------------------------- | |
| 1920 | |
| 1921 // Reserve stack space for the [[BoundArguments]]. | |
| 1922 { | |
| 1923 Label done; | |
| 1924 __ sub(sp, sp, Operand(r4, LSL, kPointerSizeLog2)); | |
| 1925 // Check the stack for overflow. We are not trying to catch interruptions | |
| 1926 // (i.e. debug break and preemption) here, so check the "real stack | |
| 1927 // 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; | |
| 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 __ ldr(ip, MemOperand(r2, r4, LSL, kPointerSizeLog2)); | |
| 1964 __ str(ip, MemOperand(sp, r0, LSL, kPointerSizeLog2)); | |
| 1965 __ add(r0, r0, Operand(1)); | |
| 1966 __ b(gt, &loop); | |
| 1967 } | |
| 1968 } | |
| 1969 __ bind(&no_bound_arguments); | |
| 1970 } | |
| 1971 | |
| 1972 } // namespace | |
| 1973 | |
| 1974 | |
| 1975 // static | |
| 1976 void Builtins::Generate_CallBoundFunction(MacroAssembler* masm) { | |
| 1977 // ----------- S t a t e ------------- | |
| 1978 // -- r0 : the number of arguments (not including the receiver) | |
| 1979 // -- r1 : the function to call (checked to be a JSBoundFunction) | |
| 1980 // ----------------------------------- | |
| 1981 __ AssertBoundFunction(r1); | |
| 1982 | |
| 1983 // Patch the receiver to [[BoundThis]]. | |
| 1984 __ ldr(ip, FieldMemOperand(r1, JSBoundFunction::kBoundThisOffset)); | |
| 1985 __ str(ip, MemOperand(sp, r0, LSL, kPointerSizeLog2)); | |
| 1986 | |
| 1987 // Push the [[BoundArguments]] onto the stack. | |
| 1988 Generate_PushBoundArguments(masm); | |
| 1989 | |
| 1990 // Call the [[BoundTargetFunction]] via the Call builtin. | |
| 1991 __ ldr(r1, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset)); | |
| 1992 __ mov(ip, Operand(ExternalReference(Builtins::kCall_ReceiverIsAny, | |
| 1993 masm->isolate()))); | |
| 1994 __ ldr(ip, MemOperand(ip)); | |
| 1995 __ add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag)); | |
| 1996 } | |
| 1997 | |
| 1998 | |
| 1999 // static | 1896 // static |
| 2000 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { | 1897 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { |
| 2001 // ----------- S t a t e ------------- | 1898 // ----------- S t a t e ------------- |
| 2002 // -- r0 : the number of arguments (not including the receiver) | 1899 // -- r0 : the number of arguments (not including the receiver) |
| 2003 // -- r1 : the target to call (can be any Object). | 1900 // -- r1 : the target to call (can be any Object). |
| 2004 // ----------------------------------- | 1901 // ----------------------------------- |
| 2005 | 1902 |
| 2006 Label non_callable, non_function, non_smi; | 1903 Label non_callable, non_function, non_smi; |
| 2007 __ JumpIfSmi(r1, &non_callable); | 1904 __ JumpIfSmi(r1, &non_callable); |
| 2008 __ bind(&non_smi); | 1905 __ bind(&non_smi); |
| 2009 __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE); | 1906 __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE); |
| 2010 __ Jump(masm->isolate()->builtins()->CallFunction(mode), | 1907 __ Jump(masm->isolate()->builtins()->CallFunction(mode), |
| 2011 RelocInfo::CODE_TARGET, eq); | 1908 RelocInfo::CODE_TARGET, eq); |
| 2012 __ cmp(r5, Operand(JS_BOUND_FUNCTION_TYPE)); | |
| 2013 __ Jump(masm->isolate()->builtins()->CallBoundFunction(), | |
| 2014 RelocInfo::CODE_TARGET, eq); | |
| 2015 __ cmp(r5, Operand(JS_PROXY_TYPE)); | 1909 __ cmp(r5, Operand(JS_PROXY_TYPE)); |
| 2016 __ b(ne, &non_function); | 1910 __ b(ne, &non_function); |
| 2017 | 1911 |
| 2018 // 1. Runtime fallback for Proxy [[Call]]. | 1912 // 1. Runtime fallback for Proxy [[Call]]. |
| 2019 __ Push(r1); | 1913 __ Push(r1); |
| 2020 // Increase the arguments size to include the pushed function and the | 1914 // Increase the arguments size to include the pushed function and the |
| 2021 // existing receiver on the stack. | 1915 // existing receiver on the stack. |
| 2022 __ add(r0, r0, Operand(2)); | 1916 __ add(r0, r0, Operand(2)); |
| 2023 // Tail-call to the runtime. | 1917 // Tail-call to the runtime. |
| 2024 __ JumpToExternalReference( | 1918 __ JumpToExternalReference( |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2064 | 1958 |
| 2065 // Tail call to the function-specific construct stub (still in the caller | 1959 // Tail call to the function-specific construct stub (still in the caller |
| 2066 // context at this point). | 1960 // context at this point). |
| 2067 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | 1961 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
| 2068 __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset)); | 1962 __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset)); |
| 2069 __ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag)); | 1963 __ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 2070 } | 1964 } |
| 2071 | 1965 |
| 2072 | 1966 |
| 2073 // static | 1967 // static |
| 2074 void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) { | |
| 2075 // ----------- S t a t e ------------- | |
| 2076 // -- r0 : the number of arguments (not including the receiver) | |
| 2077 // -- r1 : the function to call (checked to be a JSBoundFunction) | |
| 2078 // -- r3 : the new target (checked to be a constructor) | |
| 2079 // ----------------------------------- | |
| 2080 __ AssertBoundFunction(r1); | |
| 2081 | |
| 2082 // Push the [[BoundArguments]] onto the stack. | |
| 2083 Generate_PushBoundArguments(masm); | |
| 2084 | |
| 2085 // Patch new.target to [[BoundTargetFunction]] if new.target equals target. | |
| 2086 __ cmp(r1, r3); | |
| 2087 __ ldr(r3, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset), | |
| 2088 eq); | |
| 2089 | |
| 2090 // Construct the [[BoundTargetFunction]] via the Construct builtin. | |
| 2091 __ ldr(r1, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset)); | |
| 2092 __ mov(ip, Operand(ExternalReference(Builtins::kConstruct, masm->isolate()))); | |
| 2093 __ ldr(ip, MemOperand(ip)); | |
| 2094 __ add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag)); | |
| 2095 } | |
| 2096 | |
| 2097 | |
| 2098 // static | |
| 2099 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { | 1968 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { |
| 2100 // ----------- S t a t e ------------- | 1969 // ----------- S t a t e ------------- |
| 2101 // -- r0 : the number of arguments (not including the receiver) | 1970 // -- r0 : the number of arguments (not including the receiver) |
| 2102 // -- r1 : the constructor to call (checked to be a JSProxy) | 1971 // -- r1 : the constructor to call (checked to be a JSProxy) |
| 2103 // -- r3 : the new target (either the same as the constructor or | 1972 // -- r3 : the new target (either the same as the constructor or |
| 2104 // the JSFunction on which new was invoked initially) | 1973 // the JSFunction on which new was invoked initially) |
| 2105 // ----------------------------------- | 1974 // ----------------------------------- |
| 2106 | 1975 |
| 2107 // Call into the Runtime for Proxy [[Construct]]. | 1976 // Call into the Runtime for Proxy [[Construct]]. |
| 2108 __ Push(r1); | 1977 __ Push(r1); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2131 // Dispatch based on instance type. | 2000 // Dispatch based on instance type. |
| 2132 __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE); | 2001 __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE); |
| 2133 __ Jump(masm->isolate()->builtins()->ConstructFunction(), | 2002 __ Jump(masm->isolate()->builtins()->ConstructFunction(), |
| 2134 RelocInfo::CODE_TARGET, eq); | 2003 RelocInfo::CODE_TARGET, eq); |
| 2135 | 2004 |
| 2136 // Check if target has a [[Construct]] internal method. | 2005 // Check if target has a [[Construct]] internal method. |
| 2137 __ ldrb(r2, FieldMemOperand(r4, Map::kBitFieldOffset)); | 2006 __ ldrb(r2, FieldMemOperand(r4, Map::kBitFieldOffset)); |
| 2138 __ tst(r2, Operand(1 << Map::kIsConstructor)); | 2007 __ tst(r2, Operand(1 << Map::kIsConstructor)); |
| 2139 __ b(eq, &non_constructor); | 2008 __ b(eq, &non_constructor); |
| 2140 | 2009 |
| 2141 // Only dispatch to bound functions after checking whether they are | |
| 2142 // constructors. | |
| 2143 __ cmp(r5, Operand(JS_BOUND_FUNCTION_TYPE)); | |
| 2144 __ Jump(masm->isolate()->builtins()->ConstructBoundFunction(), | |
| 2145 RelocInfo::CODE_TARGET, eq); | |
| 2146 | |
| 2147 // Only dispatch to proxies after checking whether they are constructors. | 2010 // Only dispatch to proxies after checking whether they are constructors. |
| 2148 __ cmp(r5, Operand(JS_PROXY_TYPE)); | 2011 __ cmp(r5, Operand(JS_PROXY_TYPE)); |
| 2149 __ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET, | 2012 __ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET, |
| 2150 eq); | 2013 eq); |
| 2151 | 2014 |
| 2152 // Called Construct on an exotic Object with a [[Construct]] internal method. | 2015 // Called Construct on an exotic Object with a [[Construct]] internal method. |
| 2153 { | 2016 { |
| 2154 // Overwrite the original receiver with the (original) target. | 2017 // Overwrite the original receiver with the (original) target. |
| 2155 __ str(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); | 2018 __ str(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); |
| 2156 // Let the "call_as_constructor_delegate" take care of the rest. | 2019 // Let the "call_as_constructor_delegate" take care of the rest. |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2312 } | 2175 } |
| 2313 } | 2176 } |
| 2314 | 2177 |
| 2315 | 2178 |
| 2316 #undef __ | 2179 #undef __ |
| 2317 | 2180 |
| 2318 } // namespace internal | 2181 } // namespace internal |
| 2319 } // namespace v8 | 2182 } // namespace v8 |
| 2320 | 2183 |
| 2321 #endif // V8_TARGET_ARCH_ARM | 2184 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |