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 2239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2250 // -- r0 : the number of arguments (not including the receiver) | 2250 // -- r0 : the number of arguments (not including the receiver) |
2251 // -- r1 : the target to call (can be any Object). | 2251 // -- r1 : the target to call (can be any Object). |
2252 // ----------------------------------- | 2252 // ----------------------------------- |
2253 | 2253 |
2254 Label non_callable, non_function, non_smi; | 2254 Label non_callable, non_function, non_smi; |
2255 __ JumpIfSmi(r1, &non_callable); | 2255 __ JumpIfSmi(r1, &non_callable); |
2256 __ bind(&non_smi); | 2256 __ bind(&non_smi); |
2257 __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE); | 2257 __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE); |
2258 __ Jump(masm->isolate()->builtins()->CallFunction(mode, tail_call_mode), | 2258 __ Jump(masm->isolate()->builtins()->CallFunction(mode, tail_call_mode), |
2259 RelocInfo::CODE_TARGET, eq); | 2259 RelocInfo::CODE_TARGET, eq); |
2260 | |
2261 // Check if target has a [[Call]] internal method. | |
2262 __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset)); | |
2263 __ tst(r4, Operand(1 << Map::kIsCallable)); | |
2264 __ b(eq, &non_callable); | |
2265 | |
2260 __ cmp(r5, Operand(JS_BOUND_FUNCTION_TYPE)); | 2266 __ cmp(r5, Operand(JS_BOUND_FUNCTION_TYPE)); |
Benedikt Meurer
2016/03/03 13:19:34
Bound functions are always callable, so you can mo
| |
2261 __ Jump(masm->isolate()->builtins()->CallBoundFunction(tail_call_mode), | 2267 __ Jump(masm->isolate()->builtins()->CallBoundFunction(tail_call_mode), |
2262 RelocInfo::CODE_TARGET, eq); | 2268 RelocInfo::CODE_TARGET, eq); |
2263 __ cmp(r5, Operand(JS_PROXY_TYPE)); | 2269 __ cmp(r5, Operand(JS_PROXY_TYPE)); |
2264 __ b(ne, &non_function); | 2270 __ b(ne, &non_function); |
2265 | 2271 |
2266 // 0. Prepare for tail call if necessary. | 2272 // 0. Prepare for tail call if necessary. |
2267 if (tail_call_mode == TailCallMode::kAllow) { | 2273 if (tail_call_mode == TailCallMode::kAllow) { |
2268 PrepareForTailCall(masm, r0, r3, r4, r5); | 2274 PrepareForTailCall(masm, r0, r3, r4, r5); |
2269 } | 2275 } |
2270 | 2276 |
2271 // 1. Runtime fallback for Proxy [[Call]]. | 2277 // 1. Runtime fallback for Proxy [[Call]]. |
2272 __ Push(r1); | 2278 __ Push(r1); |
2273 // Increase the arguments size to include the pushed function and the | 2279 // Increase the arguments size to include the pushed function and the |
2274 // existing receiver on the stack. | 2280 // existing receiver on the stack. |
2275 __ add(r0, r0, Operand(2)); | 2281 __ add(r0, r0, Operand(2)); |
2276 // Tail-call to the runtime. | 2282 // Tail-call to the runtime. |
2277 __ JumpToExternalReference( | 2283 __ JumpToExternalReference( |
2278 ExternalReference(Runtime::kJSProxyCall, masm->isolate())); | 2284 ExternalReference(Runtime::kJSProxyCall, masm->isolate())); |
2279 | 2285 |
2280 // 2. Call to something else, which might have a [[Call]] internal method (if | 2286 // 2. Call to something else, which might have a [[Call]] internal method (if |
2281 // not we raise an exception). | 2287 // not we raise an exception). |
2282 __ bind(&non_function); | 2288 __ bind(&non_function); |
2283 // Check if target has a [[Call]] internal method. | |
2284 __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset)); | |
2285 __ tst(r4, Operand(1 << Map::kIsCallable)); | |
2286 __ b(eq, &non_callable); | |
2287 // Overwrite the original receiver the (original) target. | 2289 // Overwrite the original receiver the (original) target. |
2288 __ str(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); | 2290 __ str(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); |
2289 // Let the "call_as_function_delegate" take care of the rest. | 2291 // Let the "call_as_function_delegate" take care of the rest. |
2290 __ LoadNativeContextSlot(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, r1); | 2292 __ LoadNativeContextSlot(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, r1); |
2291 __ Jump(masm->isolate()->builtins()->CallFunction( | 2293 __ Jump(masm->isolate()->builtins()->CallFunction( |
2292 ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode), | 2294 ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode), |
2293 RelocInfo::CODE_TARGET); | 2295 RelocInfo::CODE_TARGET); |
2294 | 2296 |
2295 // 3. Call to something that is not callable. | 2297 // 3. Call to something that is not callable. |
2296 __ bind(&non_callable); | 2298 __ bind(&non_callable); |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2565 } | 2567 } |
2566 } | 2568 } |
2567 | 2569 |
2568 | 2570 |
2569 #undef __ | 2571 #undef __ |
2570 | 2572 |
2571 } // namespace internal | 2573 } // namespace internal |
2572 } // namespace v8 | 2574 } // namespace v8 |
2573 | 2575 |
2574 #endif // V8_TARGET_ARCH_ARM | 2576 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |