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 2231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2242 } | 2242 } |
2243 | 2243 |
2244 // Dispatch to Call or Construct depending on whether new.target is undefined. | 2244 // Dispatch to Call or Construct depending on whether new.target is undefined. |
2245 { | 2245 { |
2246 __ CompareRoot(r3, Heap::kUndefinedValueRootIndex); | 2246 __ CompareRoot(r3, Heap::kUndefinedValueRootIndex); |
2247 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET, eq); | 2247 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET, eq); |
2248 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 2248 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
2249 } | 2249 } |
2250 } | 2250 } |
2251 | 2251 |
| 2252 // static |
| 2253 void Builtins::Generate_CallForwardVarargs(MacroAssembler* masm, |
| 2254 Handle<Code> code) { |
| 2255 // ----------- S t a t e ------------- |
| 2256 // -- r1 : the target to call (can be any Object) |
| 2257 // -- r2 : start index (to support rest parameters) |
| 2258 // -- lr : return address. |
| 2259 // -- sp[0] : thisArgument |
| 2260 // ----------------------------------- |
| 2261 |
| 2262 // Check if we have an arguments adaptor frame below the function frame. |
| 2263 Label arguments_adaptor, arguments_done; |
| 2264 __ ldr(r3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
| 2265 __ ldr(ip, MemOperand(r3, CommonFrameConstants::kContextOrFrameTypeOffset)); |
| 2266 __ cmp(ip, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 2267 __ b(eq, &arguments_adaptor); |
| 2268 { |
| 2269 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 2270 __ ldr(r0, FieldMemOperand(r0, JSFunction::kSharedFunctionInfoOffset)); |
| 2271 __ ldr(r0, FieldMemOperand( |
| 2272 r0, SharedFunctionInfo::kFormalParameterCountOffset)); |
| 2273 __ mov(r3, fp); |
| 2274 } |
| 2275 __ b(&arguments_done); |
| 2276 __ bind(&arguments_adaptor); |
| 2277 { |
| 2278 // Load the length from the ArgumentsAdaptorFrame. |
| 2279 __ ldr(r0, MemOperand(r3, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 2280 } |
| 2281 __ bind(&arguments_done); |
| 2282 |
| 2283 Label stack_empty, stack_done, stack_overflow; |
| 2284 __ SmiUntag(r0); |
| 2285 __ sub(r0, r0, r2, SetCC); |
| 2286 __ b(le, &stack_empty); |
| 2287 { |
| 2288 // Check for stack overflow. |
| 2289 Generate_StackOverflowCheck(masm, r0, r2, &stack_overflow); |
| 2290 |
| 2291 // Forward the arguments from the caller frame. |
| 2292 { |
| 2293 Label loop; |
| 2294 __ add(r3, r3, Operand(kPointerSize)); |
| 2295 __ mov(r2, r0); |
| 2296 __ bind(&loop); |
| 2297 { |
| 2298 __ ldr(ip, MemOperand(r3, r2, LSL, kPointerSizeLog2)); |
| 2299 __ push(ip); |
| 2300 __ sub(r2, r2, Operand(1), SetCC); |
| 2301 __ b(ne, &loop); |
| 2302 } |
| 2303 } |
| 2304 } |
| 2305 __ b(&stack_done); |
| 2306 __ bind(&stack_overflow); |
| 2307 __ TailCallRuntime(Runtime::kThrowStackOverflow); |
| 2308 __ bind(&stack_empty); |
| 2309 { |
| 2310 // We just pass the receiver, which is already on the stack. |
| 2311 __ mov(r0, Operand(0)); |
| 2312 } |
| 2313 __ bind(&stack_done); |
| 2314 |
| 2315 __ Jump(code, RelocInfo::CODE_TARGET); |
| 2316 } |
| 2317 |
2252 namespace { | 2318 namespace { |
2253 | 2319 |
2254 // Drops top JavaScript frame and an arguments adaptor frame below it (if | 2320 // Drops top JavaScript frame and an arguments adaptor frame below it (if |
2255 // present) preserving all the arguments prepared for current call. | 2321 // present) preserving all the arguments prepared for current call. |
2256 // Does nothing if debugger is currently active. | 2322 // Does nothing if debugger is currently active. |
2257 // ES6 14.6.3. PrepareForTailCall | 2323 // ES6 14.6.3. PrepareForTailCall |
2258 // | 2324 // |
2259 // Stack structure for the function g() tail calling f(): | 2325 // Stack structure for the function g() tail calling f(): |
2260 // | 2326 // |
2261 // ------- Caller frame: ------- | 2327 // ------- Caller frame: ------- |
(...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3056 __ bkpt(0); | 3122 __ bkpt(0); |
3057 } | 3123 } |
3058 } | 3124 } |
3059 | 3125 |
3060 #undef __ | 3126 #undef __ |
3061 | 3127 |
3062 } // namespace internal | 3128 } // namespace internal |
3063 } // namespace v8 | 3129 } // namespace v8 |
3064 | 3130 |
3065 #endif // V8_TARGET_ARCH_ARM | 3131 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |