| 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 |