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_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.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 2184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2195 | 2195 |
2196 Label non_callable, non_function, non_smi; | 2196 Label non_callable, non_function, non_smi; |
2197 __ JumpIfSmi(edi, &non_callable); | 2197 __ JumpIfSmi(edi, &non_callable); |
2198 __ bind(&non_smi); | 2198 __ bind(&non_smi); |
2199 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 2199 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
2200 __ j(equal, masm->isolate()->builtins()->CallFunction(mode, tail_call_mode), | 2200 __ j(equal, masm->isolate()->builtins()->CallFunction(mode, tail_call_mode), |
2201 RelocInfo::CODE_TARGET); | 2201 RelocInfo::CODE_TARGET); |
2202 __ CmpInstanceType(ecx, JS_BOUND_FUNCTION_TYPE); | 2202 __ CmpInstanceType(ecx, JS_BOUND_FUNCTION_TYPE); |
2203 __ j(equal, masm->isolate()->builtins()->CallBoundFunction(tail_call_mode), | 2203 __ j(equal, masm->isolate()->builtins()->CallBoundFunction(tail_call_mode), |
2204 RelocInfo::CODE_TARGET); | 2204 RelocInfo::CODE_TARGET); |
| 2205 |
| 2206 // Check if target has a [[Call]] internal method. |
| 2207 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsCallable); |
| 2208 __ j(zero, &non_callable); |
| 2209 |
2205 __ CmpInstanceType(ecx, JS_PROXY_TYPE); | 2210 __ CmpInstanceType(ecx, JS_PROXY_TYPE); |
2206 __ j(not_equal, &non_function); | 2211 __ j(not_equal, &non_function); |
2207 | 2212 |
2208 // 0. Prepare for tail call if necessary. | 2213 // 0. Prepare for tail call if necessary. |
2209 if (tail_call_mode == TailCallMode::kAllow) { | 2214 if (tail_call_mode == TailCallMode::kAllow) { |
2210 PrepareForTailCall(masm, eax, ebx, ecx, edx); | 2215 PrepareForTailCall(masm, eax, ebx, ecx, edx); |
2211 } | 2216 } |
2212 | 2217 |
2213 // 1. Runtime fallback for Proxy [[Call]]. | 2218 // 1. Runtime fallback for Proxy [[Call]]. |
2214 __ PopReturnAddressTo(ecx); | 2219 __ PopReturnAddressTo(ecx); |
2215 __ Push(edi); | 2220 __ Push(edi); |
2216 __ PushReturnAddressFrom(ecx); | 2221 __ PushReturnAddressFrom(ecx); |
2217 // Increase the arguments size to include the pushed function and the | 2222 // Increase the arguments size to include the pushed function and the |
2218 // existing receiver on the stack. | 2223 // existing receiver on the stack. |
2219 __ add(eax, Immediate(2)); | 2224 __ add(eax, Immediate(2)); |
2220 // Tail-call to the runtime. | 2225 // Tail-call to the runtime. |
2221 __ JumpToExternalReference( | 2226 __ JumpToExternalReference( |
2222 ExternalReference(Runtime::kJSProxyCall, masm->isolate())); | 2227 ExternalReference(Runtime::kJSProxyCall, masm->isolate())); |
2223 | 2228 |
2224 // 2. Call to something else, which might have a [[Call]] internal method (if | 2229 // 2. Call to something else, which might have a [[Call]] internal method (if |
2225 // not we raise an exception). | 2230 // not we raise an exception). |
2226 __ bind(&non_function); | 2231 __ bind(&non_function); |
2227 // Check if target has a [[Call]] internal method. | |
2228 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsCallable); | |
2229 __ j(zero, &non_callable, Label::kNear); | |
2230 // Overwrite the original receiver with the (original) target. | 2232 // Overwrite the original receiver with the (original) target. |
2231 __ mov(Operand(esp, eax, times_pointer_size, kPointerSize), edi); | 2233 __ mov(Operand(esp, eax, times_pointer_size, kPointerSize), edi); |
2232 // Let the "call_as_function_delegate" take care of the rest. | 2234 // Let the "call_as_function_delegate" take care of the rest. |
2233 __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, edi); | 2235 __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, edi); |
2234 __ Jump(masm->isolate()->builtins()->CallFunction( | 2236 __ Jump(masm->isolate()->builtins()->CallFunction( |
2235 ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode), | 2237 ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode), |
2236 RelocInfo::CODE_TARGET); | 2238 RelocInfo::CODE_TARGET); |
2237 | 2239 |
2238 // 3. Call to something that is not callable. | 2240 // 3. Call to something that is not callable. |
2239 __ bind(&non_callable); | 2241 __ bind(&non_callable); |
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2660 | 2662 |
2661 __ bind(&ok); | 2663 __ bind(&ok); |
2662 __ ret(0); | 2664 __ ret(0); |
2663 } | 2665 } |
2664 | 2666 |
2665 #undef __ | 2667 #undef __ |
2666 } // namespace internal | 2668 } // namespace internal |
2667 } // namespace v8 | 2669 } // namespace v8 |
2668 | 2670 |
2669 #endif // V8_TARGET_ARCH_IA32 | 2671 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |